题目:
给你两个按 非递减顺序 排列的整数数组 nums1
和 nums2
,另有两个整数 m
和 n
,分别表示 nums1
和 nums2
中的元素数目。
请你 合并 nums2
到 nums1
中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1
中。为了应对这种情况,nums1
的初始长度为 m + n
,其中前 m
个元素表示应合并的元素,后 n
个元素为 0
,应忽略。nums2
的长度为 n
。
示例 1:
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3 输出:[1,2,2,3,5,6] 解释:需要合并 [1,2,3] 和 [2,5,6] 。 合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。
示例 2:
输入:nums1 = [1], m = 1, nums2 = [], n = 0 输出:[1] 解释:需要合并 [1] 和 [] 。 合并结果是 [1] 。
示例 3:
输入:nums1 = [0], m = 0, nums2 = [1], n = 1 输出:[1] 解释:需要合并的数组是 [] 和 [1] 。 合并结果是 [1] 。 注意,因为 m = 0 ,所以 nums1 中没有元素。nums1 中仅存的 0 仅仅是为了确保合并结果可以顺利存放到 nums1 中。
提示:
nums1.length == m + n
nums2.length == n
0 <= m, n <= 200
1 <= m + n <= 200
-109 <= nums1[i], nums2[j] <= 109
解决:
解法1:利用Arrays中的sort方法排序直接求解
public void merge(int[] nums1,int m,int[] nums2,int n) {for(int i=0;i<n;i++){nums1[m+i]=nums2[i];}Arrays.sort(nums1);}
快速排序,时间复杂度为O((m+n)log(m+n))。代码效率不是特别高。其最大的问题是,题目给的数组元素本来是有序的,但这样混起来之后用sort排序相当于又重新排序了一遍,即没有充分利用元素的有序性。
解法2:用双指针
每次从两个数组的头部各取出一个数比较,把比较小的结果复制到临时数组中,再把比较小数所在数组指针后移一位。把两个数组元素都复制到临时数组后,临时数组的结果就是排序以后的结果了。再把临时数组的元素复制到nums1。这样的话两个数组都只循环了一遍,时间复杂度为O(m+n)。空间复杂度也是O(m+n)。
public void merge(int[] nums1,int m,int[] nums2,int n) {int k=m+n;int[] temp=new int[k];for(int index=0,nums1Index=0,nums2Index=0;index<k;index++){if(nums1Index>=m) {//nums1数组已经取完,接下来完全取nums2数组的值temp[index]=nums2[nums2Index++];}else if(nums2Index>=n){temp[index]=nums1[nums1Index++];}else if(nums1[nums1Index]<nums2[nums2Index]){//nums1数组元素值小于nums2数组元素值,取nums1数组的值temp[index]=nums1[nums1Index++];}else{temp[index]=nums2[nums2Index++];}}for(int i=0;i<k;i++){nums1[i]=temp[i];}}
解法3:用双指针,倒序处理
把nums2的最后一个元素与nums1的有效的最后一个元素比较,把大的放在nums1的最后一个0的位置。再把刚才的指针往前移一位,再比较这样就用到nums1的空间了,不用引入临时数组。这样时间复杂度为O(m+n),空间复杂度为O(m)。
public void merge(int[] nums1,int m,int[] nums2,int n) {int k=m+n;for(int index=k-1,nums1Index=m-1,nums2Index=n-1;index>=0;index--){if(nums1Index<0) {//nums1数组已经取完,接下来完全取nums2数组的值nums1[index]=nums2[nums2Index--];}else if(nums2Index<0){break;}else if(nums1[nums1Index]>nums2[nums2Index]){//nums1数组元素值大于nums2数组元素值,取nums1数组的值nums1[index]=nums1[nums1Index--];}else{nums1[index]=nums2[nums2Index--];}}}
加油加油^_^