LeetCode刷题笔记(Merge Sorted Array)

今天刷的题目思路不难,但想把代码做得更完美还是有一定难度的。

 具体题目如下:

Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array.

Note:

The number of elements initialized in nums1 and nums2 are m and n respectively.
You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2.
Example:

Input:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6],       n = 3

Output: [1,2,2,3,5,6]

解答如下:

方法一

这里用了库函数sort走了捷径, 所以并不是最好的答案,还得继续探索最好的答案。代码中sort(nums1.begin(),nums1.end())默认是从小到大排序。请注意vector是向量容器,所以应该用到nums1.begin()表示向量的首地址, nums1.end()表示向量的尾地址。而数组的数组名是首地址,尾地址=首地址+数组个数。

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int k = 0;
        for (int i = 0; i < nums1.size(); i++)//该层for循环只为去掉nums1中的0元素
            if(nums1[i] != 0 )
            {
                swap(nums1[k], nums1[i]);
                k++;
            }
        k=0;
        for (int i = 0; i < nums2.size(); i++)//该层for循环只为去掉nums2中的0元素
            if(nums2[i] != 0 )
            {
                swap(nums2[k], nums2[i]);
                k++;
            }
        nums1.resize(m+n);//将nums1按m+n的长度重置大小,用于存放所有非零元素
        for (int i = m; i < m+n; i++)//将nums2中非零元素紧接着nums1中非零元素后赋值
                nums1[i] = nums2[i-m];
        sort(nums1.begin(),nums1.end());//将nums1按从小到大排序

    }
};

 提交后的结果如下:

 

方法二

在方法一的基础上,笔者想先把nums1和nums2直接拼接,然后通过交换的手段将所有的非0元素前移,0元素后移。最后将nums1按m+n大小重置并排序。这里有个样例比较坑:Your input:[-1,0,0,3,3,3,0,0,0] 6; [1,2,2] 3  Output:[-1,0,0,1,2,2,3,3,3].注:从样例可以知道,题目并不是要去掉所有的0元素。

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int k = 0;
        nums1.resize(nums1.size()+nums2.size());
        for (int i = nums1.size()-nums2.size(); i < nums1.size(); i++)
            nums1[i] = nums2[i-nums1.size()+nums2.size()];
        for (int i = 0; i < nums1.size(); i++)
            if( nums1[i] !=0  )
                swap(nums1[k++], nums1[i]);
        nums1.resize(m+n);
        sort(nums1.begin(),nums1.end());
    }
};

提交后的结果如下:

方法三:

笔者当时想到的是从头往后依次比较,而网上给出的大部分却是从后往前比较,可能是因为这样更合适吧。

解题思路: 针对nums1和nums2这两个数组我们都先从最后面的元素开始比较,找到一个较大的放到nums1中的n+m-1位置。那个较小的元素再和较大元素数组中的倒数第二个元素进行比较,之后把较大的元素放在n+m-2的位置上,依次类推,最后我们就可以得到一个排好顺序的nums1数组。

通过学习了网上关于此题的解法后,顿时发现自己由于忽视了题目中的一些条件而把题目解得复杂了。请注意条件中明确指出:①,nums1和nums2这两个数组中的元素都是已经排好顺序的(默认应该是从小到大排序,0元素不一定在最后面);②,nums1数组的位数是大于等于n+m的。因此进行两两对比后直接赋值给nums1即可,根本无需在创建一个数组来保存这些数。

//复杂容易理解版本
class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int i1 = m - 1, i2 = n - 1, k = m + n - 1;
        while (i1>= 0 && i2>=0){
            if (nums1[i1] < nums2[i2])
            {
                nums1[k--] = nums2[i2--];
            }
            else{
                nums1[k--] = nums1[i1--];
            }
        }
        while (i2 >= 0){
            nums1[k--] = nums2[i2--];
        }

        return;
    }
};

//简洁不易理解版
class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int i1 = m - 1, i2 = n - 1, k = m + n - 1;
        while (i2 >= 0) {
            nums1[k--] = i1 >= 0 && nums1[i1] > nums2[i2] ? nums1[i1--] : nums2[i2--];
        }
    }
};

提交后的结果如下:

日积月累,与君共进,增增小结,未完待续。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值