给你两个有序整数数组nums1 和 nums2,请你将 nums2 合并到nums1中,使 nums1 成为一个有序数组。 初始化nums1 和 nums2 的元素数量分别为m 和 n 。你可以假设nums1 的空间大小等于m + n,这样它就有足够的空间保存来自 nums2 的元素。

示例 1:

输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]

示例 2:

输入:nums1 = [1], m = 1, nums2 = [], n = 0
输出:[1]

提示:

nums1.length == m + n
nums2.length == n
0 <= m, n <= 200
1 <= m + n <= 200
-109 <= nums1[i], nums2[i] <= 109

来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/merge-sorted-array

#解法 该题有多种解法,朴素解法是先将两个数组合并,然后再进行排序。但是题目给出的数组已经是有序的了,要充分利用该信息。 如果从有序的数组的头部每次取出一个元素进行比较,选取较小的那个,那么选取判断后弹出的数据将会是数组1和数组2合并后的结果。因此需要建立辅助空间来存储选取后弹出的结果。 该空间的大小至少是m,根据题目来看最大是200. 我直接偷了懒,直接创建一个新的数组来存储(反正看的是后面一个解法)

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int a=0,b=0;
        int s = 0;
        int len = m+n;
        int min = m < n ? m : n;
        int[] nums3 = new int[m+n];
        // 从两个列表中的未移动的部分头部哪个大
        while(a <m && b <n) {
            if(nums1[a]<nums2[b]){
                nums3[s]=nums1[a++];
            } else {
                nums3[s]=nums2[b++];
            }
            s++;
        }
        // 将剩余nums1中的数据移动到nums3
        while(a<m) nums3[s++]=nums1[a++];
    // 将剩余nums2中的数据移动到nums3
    while(b&lt;n) nums3[s++]=nums2[b++];
    // 覆盖nums1
    for(int i=0;i&lt;len;i++) {
        nums1[i]=nums3[i];
    }
}

}

上述解法存在的问题是需要额外的存储空间来存储,已知nums1已经是可以存储所有的结果的数组,能够在不创建新数组的情况完成合并? 上一种解法是从头部开始遍历,所以放置元素的时候与原数组出现了冲突,如果利用不会冲突的部分,也就nums1的尾部来存储元素将会解决该冲突。 与从头部遍历的方法的差异只需要替换遍历的方向即可。

class Solution {
    private static final int MIN = -1;
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int a=m-1,b=n-1;
        int s = m + n - 1;
    // 两个列表都不为空的情况先移动大的
    while(a &gt; MIN &amp;&amp; b &gt; MIN) {
        if(nums1[a]&gt;nums2[b]){
            nums1[s]=nums1[a--];
        } else {
            nums1[s]=nums2[b--];
        }
        s--;
    }
    // 将剩余nums1中的数据移动到nums1
    while(a&gt;MIN) nums1[s--]=nums1[a--];
// 将剩余nums2中的数据移动到nums1
while(b&amp;gt;MIN) nums1[s--]=nums2[b--];

}

}