返回

如何将两个有序数组合并成一个有序数组?

前端

好的,以下是算法练习第22题的解答:

算法练习第22道-合并两个有序数组

题目:
给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。

方法一:使用临时数组

步骤:

  1. 定义一个新的数组 nums3,长度为 m + n。
  2. 使用两个指针 i 和 j 分别指向 nums1 和 nums2 的第一个元素。
  3. 比较 nums1[i] 和 nums2[j],将较小的元素放入 nums3[k] 中,并移动指针 i 或 j 到下一个元素。
  4. 重复步骤 3,直到其中一个数组的指针到达数组末尾。
  5. 将剩余元素从另一个数组复制到 nums3 中。

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

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

示例代码:

def merge_arrays(nums1, m, nums2, n):
    """
    合并两个有序数组,使合并后的数组仍然有序。

    Args:
        nums1 (list): 第一个有序数组。
        m (int): nums1 中有意义的元素数量。
        nums2 (list): 第二个有序数组。
        n (int): nums2 中有意义的元素数量。

    Returns:
        list: 合并后的有序数组。
    """

    # 定义一个新的数组 nums3 来存储合并后的数组
    nums3 = [0] * (m + n)

    # 定义两个指针 i 和 j 分别指向 nums1 和 nums2 的第一个元素
    i = 0
    j = 0

    # 将 nums1 和 nums2 中较小的元素放入 nums3 中
    while i < m and j < n:
        if nums1[i] <= nums2[j]:
            nums3[i + j] = nums1[i]
            i += 1
        else:
            nums3[i + j] = nums2[j]
            j += 1

    # 将剩余元素从 nums1 或 nums2 复制到 nums3 中
    while i < m:
        nums3[i + j] = nums1[i]
        i += 1

    while j < n:
        nums3[i + j] = nums2[j]
        j += 1

    # 返回合并后的有序数组
    return nums3

方法二:就地合并

步骤:

  1. 从 nums1 的末尾开始,将元素向右移动 n 个位置。
  2. 从 nums2 的末尾开始,将元素复制到 nums1 的空位置中。
  3. 使用两个指针 i 和 j 分别指向 nums1 和 nums2 的末尾。
  4. 比较 nums1[i] 和 nums2[j],将较小的元素放入 nums1[i + j] 中,并移动指针 i 或 j 到下一个元素。
  5. 重复步骤 4,直到其中一个指针到达数组开头。

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

空间复杂度: O(1)

示例代码:

def merge_arrays_in_place(nums1, m, nums2, n):
    """
    就地合并两个有序数组,使合并后的数组仍然有序。

    Args:
        nums1 (list): 第一个有序数组。
        m (int): nums1 中有意义的元素数量。
        nums2 (list): 第二个有序数组。
        n (int): nums2 中有意义的元素数量。

    Returns:
        list: 合并后的有序数组。
    """

    # 从 nums1 的末尾开始,将元素向右移动 n 个位置
    for i in range(m - 1, -1, -1):
        nums1[i + n] = nums1[i]

    # 从 nums2 的末尾开始,将元素复制到 nums1 的空位置中
    i = m + n - 1
    j = n - 1

    # 将 nums1 和 nums2 中较小的元素放入 nums1 中
    while i >= 0 and j >= 0:
        if nums1[i] <= nums2[j]:
            nums1[i + j] = nums1[i]
            i -= 1
        else:
            nums1[i + j] = nums2[j]
            j -= 1

    # 返回合并后的有序数组
    return nums1

结论:

本文介绍了两种合并两个有序数组的方法:使用临时数组和就地合并。这两种方法都具有相同的时间复杂度和空间复杂度。您可以根据自己的需要选择一种方法来实现。