88. 合并两个有序数组

https://leetcode.cn/problems/merge-sorted-array/

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        // 要求O(m + n)
        // 双指针,指针i遍历nums1,指针j遍历nums2
        // 判断两个指针指向的数值大小,小的存入额外的结果数组,且指针右移
        int i = 0, j = 0, idx = 0;
        int[] res = new int[m + n];
        while (i < m && j < n) {
            if (nums1[i] < nums2[j]) {
                res[idx] = nums1[i++];
            } else {
                res[idx] = nums2[j++];
            }
            idx++;
        }
        if (i < m) {
            for(;i<m;i++,idx++) res[idx] = nums1[i];
        } else {
            for(;j<n;j++,idx++) res[idx] = nums2[j];
        }
        for (idx = 0; idx < m + n; idx++) nums1[idx] = res[idx];
    }
}
class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        // 要求O(m + n)
        // 小优化,倒序可以不使用额外的结果数组,直接将结果存入nums1,因为是从后往前填,从大到小,可以简单数学证明不会发生覆盖,或者瞪眼法也能看出来
        // 假设后续0段从nums2填了y个,那么nums1填了n-y个,那么nums1有意义的数值段末尾则有n-y个位置失效了,不具有意义了,nums2也恰好剩下n-y个数值需要填充,故得证
        // 倒序指针都左移
        int i = m - 1, j = n - 1, idx = m + n - 1;
        while (j >= 0) {
            if (i >= 0 && nums1[i] > nums2[j]) {
                nums1[idx--] = nums1[i--];
            } else {
                nums1[idx--] = nums2[j--];
            }
        }
    }
}

 

posted @ 2026-05-07 15:31  风乐  阅读(20)  评论(0)    收藏  举报