欢迎访问宙启技术站
智能推送

如何使用Java编写一个函数来将两个有序数组合并为一个有序数组?

发布时间:2023-06-19 14:23:23

题目要求编写一个函数,将两个有序数组合并为一个有序数组。这个问题看似简单,但可以发现需要处理的细节还是挺多的。接下来我将用1000字论述如何使用Java编写这个函数。

1.暴力合并

我们最基本的想法就是从头到尾扫描两个数组,比较元素大小,再将它们放入新的数组中。时间复杂度为O(n+m),n和m分别为两个数组的长度。

代码实现如下:

public static void merge(int[] nums1, int m, int[] nums2, int n) {
    int[] nums = new int[m + n];
    int i = 0;
    int j = 0;
    int k = 0;

    while (i < m && j < n) {
        if (nums1[i] <= nums2[j]) {
            nums[k++] = nums1[i++];
        } else {
            nums[k++] = nums2[j++];
        }
    }

    while (i < m) {
        nums[k++] = nums1[i++];
    }

    while (j < n) {
        nums[k++] = nums2[j++];
    }

    System.arraycopy(nums, 0, nums1, 0, m + n);
}

这个代码实现还是比较简单的,不赘述。

2.双指针法

有一种方法被称为双指针法,它可以将空间复杂度降至O(1)。时间复杂度为O(n+m),n和m分别为两个数组的长度。具体操作如下:

定义两个指针i和j分别指向两个数组的头部,比较两个指针所指向的元素大小,将较小的元素放入新的数组中,然后指针向后移动一位。需要注意的是,在一次比较中,如果有一个指针到达了数组的尾部,则直接将剩余数组中的元素插入到新数组中。

代码如下:

public static void merge(int[] nums1, int m, int[] nums2, int n) {
    int[] nums = new int[m + n];
    int i = 0;
    int j = 0;
    int k = 0;

    while (i < m && j < n) {
        if (nums1[i] <= nums2[j]) {
            nums[k++] = nums1[i++];
        } else {
            nums[k++] = nums2[j++];
        }
    }

    while (i < m) {
        nums[k++] = nums1[i++];
    }

    while (j < n) {
        nums[k++] = nums2[j++];
    }

    System.arraycopy(nums, 0, nums1, 0, m + n);
}

3.从后往前合并

其实还有一种更加巧妙的方法,可以将空间复杂度降至O(1),不需要创建新数组。从后往前遍历,将较大的元素从nums1或nums2中复制到nums1的后面。时间复杂度O(n+m),空间复杂度O(1)。

代码如下:

public static void merge(int[] nums1, int m, int[] nums2, int n) {
    int i = m - 1;
    int j = n - 1;
    int k = m + n - 1;

    while (i >= 0 && j >= 0) {
        if (nums1[i] >= nums2[j]) {
            nums1[k--] = nums1[i--];
        } else {
            nums1[k--] = nums2[j--];
        }
    }

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

到这里,本文就结束了。从这个问题我们可以看到,对于同一个问题,有时候需要不同的方法去解决。希望这个文章可以对大家有所帮助。