合并两个有序数组


准大三生,最近一直在准备寒假实习,想要每天坚持刷Leetcode上面的一些经典面试算法题,选定了掘金作为自己的记录的平台!

面试经典150题
数组/字符串
合并两个有序数组(https://leetcode.cn/studyplan/top-interview-150/)

题目:给你两个按 非递减顺序 排列的整数数组 `nums1` 和 `nums2`,另有两个整数 `m` 和 `n` ,分别表示 `nums1` 和 `nums2` 中的元素数目。请你 合并`nums2` 到 `nums1` 中,使合并后的数组同样按 非递减顺序排列。

注意:最终,合并后数组不应由函数返回,而是存储在数组 `nums1` 中。为了应对这种情况,`nums1` 的初始长度为 `m + n`,其中前 `m` 个元素表示应合并的元素,后 `n` 个元素为 `0` ,应忽略。`nums2` 的长度为 `n` 。

不用多想,若是单纯考虑最小的时间复杂度以及空间复杂度下完成,一般是采用双指针,题目中刚好要求要让合并后的元素存储进nums1数组中,则此时的空间复杂度相对来说也是极小的,我们可以沿着此思路进行求解:

1、刚开始的思路
对于nums1数组,采用双指针,从左到右依次进行存储,在存储之前进行比较nums1和nums2的元素大小(本质上就是先选择小的元素放置在nums1数组中的左侧)

代码如下:

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int k = 0,  i = 0, j = 0;
        while(k < m + n){
            if( i >= m){
                nums1[k] = nums2[j];
                j++;
            }else if( j >= n){
                nums1[k] = nums1[i];
                i++; 
            }else if(nums1[i] <= nums2[j]){
                nums1[k] = nums1[i];
                i++;
            }else{
                nums1[k] = nums2[j];
                j++;
            }
            k++;
        }
    }
};

  问题是将两个数组中每次比较较小的元素往nums1中存储的时候,有可能会产生覆盖的情况,因为若是nums2中元素存储的过快,然后nums1中的指针i记录的比较的数组元素将会被更新的nums1的元素覆盖,造成最终生成的数组会出现多个一样的值!

解决办法:若是想要采用这种办法必须重新定义一个数组,将nums1和nums2中的元素全部存储进去后,最后一个for循环拷贝所有的进入
nums1数组即可!缺点是耗费额外的空间,空间复杂度直接增大一倍!

2.相对来说,较优的思路

想了好久,从评论区看到的解题思路,为了避免使用额外的空间,合理使用nums1数组的空间,这里对于nums1和nums2原始数据采用从右边向左的存储进行,即从大到小

相关代码也是要简单不少:

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int k = m + n - 1,  i = m - 1, j = n - 1;
        //参考题解,从后往前进行
        while(k >= 0){
            if(i >= 0 && j >= 0){
                if(nums1[i] >= nums2[j]){
                    nums1[k] = nums1[i];
                    i--;
                }else{
                    nums1[k] = nums2[j];
                    j--;
                }
            }else if(j >= 0 && i < 0){
                    while(j >= 0){
                        nums1[j] = nums2[j];
                        j--;
                    }
                    break;
            }else{
                break;
            }
            k--;
        }   
    }
};

2023年9月6号

posted @ 2023-09-06 22:43  Vincetes  阅读(22)  评论(0编辑  收藏  举报