leetcode 88. 合并两个有序数组


本题 题目链接

题目描述


我的题解

!!!记住:一般而言,对于有序数组可以通过 双指针法 达到 O(n + m) 的时间复杂度。

(要开辟新空间的方法就不说了)

方法:双指针(从后往前)

思路分析

  • 不开辟新空间,直接在 nums1 数组上操作。
  • 一般而言我们会想到从前往后分别遍历 nums1 和 nums2。但是这样的话,交换数字之类的超麻烦,似乎也不容易实现!
  • 那么,既然能从前往后,反正又是有序数组,那我也能从后往前呀,似乎并没有啥区别。能前往后,自然也能后往前嘛。
  • 而前往后的缺点就是空间不够。那后往前呢?我们最终是要把 nums2 放进 nums1 里的,那 nums1 后面不是还有 n 个位置的空间嘛!空间这么多,就不怕交换位置造成的麻烦啦!
  • 指针 i、j 分别指向 nums1、nums2 最后一个元素,而 cur 指针为当前可以放入的位置。

时间复杂度:O(n+m)
空间复杂度:O(1)

代码如下

    public void merge(int[] nums1, int m, int[] nums2, int n) {

        if (n == 0 || nums2 == null || nums1 == null) return;
        if (m == 0) {
            if (nums2 != null) {
                for (int i = 0; i < n; i++)
                    nums1[i] = nums2[i];
            }
            return;
        }

        int i = m - 1;
        int j = n - 1;
        int cur = m + n - 1;
        while (j >= 0) {
            if (nums1[i] > nums2[j]) {
                nums1[cur--] = nums1[i--];
            } else {
                nums1[cur--] = nums2[j--];
            }
            if (i == -1) { // num1前m个元素的遍历结束了
                while (j != -1) nums1[cur--] = nums2[j--];
            }
        }
        // System.out.println(Arrays.toString(nums1));
    }

原文地址:https://www.cnblogs.com/duduwy/p/13413638.html