[LeetCode-88]-Merge Sorted Array(有序数组合并)

0. 题目相关

【题目解读】
给定两个有序数组,对数组进行合并操作。要求合并后的数组依旧有序。

【原题描述】原题链接
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]

【难度】Easy

1. Solution

题目挺简单的,两个都是有序的,所以这里想到了最简单便捷的方法,先将数组2放到数组1的最后,再对相加后的数组进行排序操作。

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        if(nums1.size() < m + n)
        {
            return;
        }
        
        vector<int>::iterator it = nums1.begin();
        
        //指针指到有效的最后一位
        it = it + m;
        for(int i = 0; i < n; i++) 
        {
            *it++ = nums2[i];
        }
        sort(nums1.begin(), nums1.begin() + m + n);     
    }
};

代码提交情况:
在这里插入图片描述
其他版本代码:

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        if(nums1.size() < m + n)
        {
            return;
        }
        
        vector<int>::iterator it = nums1.begin();
        nums1.insert(it+m, nums2.begin(), nums2.begin() + n); //直接进行插入操作
        nums1.erase(nums1.begin()+m+n,nums1.begin()+m+n+n); //删除多的元素
        
        sort(nums1.begin(), nums1.begin() + m + n);     
    }
};

上述代码提交结果:
在这里插入图片描述

2. 其他改进方案

如果从前面开始操作,中间比较将会进行多次移位操作,此时带来了巨大的内存开销。

由于是两个有序数组,此时可以充分利用有序这一点。据此可以获知,最终的序列中,最大的一个数值不是来自于nums1的最后一个,就是来自于nums2的最后一个,所以可以利用这一点特性,从两个数组的最后一个数据进行比较,避免多次移位操作,就只用比较一次就可以把数据放到最终位置。

实现代码:

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        if(nums1.size() < m + n)
        {
            return;
        }
        
        int i = m - 1; //nums1的最后一个有效元素的下标
        int j = n - 1; //nums2的最后一个下标
        int end = m + n - 1;
        while(i >= 0 && j >= 0)
        {
            if(nums1[i] >= nums2[j])
            {
                nums1[end--] = nums1[i--];
            }else
            {
                nums1[end--] = nums2[j--];
            }
        }
        
         //以下两个while代码只会执行一个
         while(i >= 0)
         {
            nums1[end--] = nums1[i--];                 
         }

         while(j >= 0)
         {
            nums1[end--] = nums2[j--];                 
         }
    }
};

评估结果:
在这里插入图片描述

另,上述代码中,两个while只执行一个部分,这里实际上还可以进行优化,可以删除 while(i >= 0) 的处理,因为此时end就是i了,这里的操作相当于是自己给自己赋值。所以最终的代码为:

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        if(nums1.size() < m + n)
        {
            return;
        }
        
        int i = m - 1; //nums1的最后一个有效元素的下标
        int j = n - 1; //nums2的最后一个下标
        int end = m + n - 1;
        while(i >= 0 && j >= 0)
        {
            if(nums1[i] >= nums2[j])
            {
                nums1[end--] = nums1[i--];
            }else
            {
                nums1[end--] = nums2[j--];
            }
        }
        
         while(j >= 0)
         {
            nums1[end--] = nums2[j--];                 
         }
    }
};
发布了134 篇原创文章 · 获赞 30 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/donaldsy/article/details/102538501
今日推荐