返回

LeetCode.88 合并两个有序数组,合并有序数组技巧全方位解析

闲谈

数组作为一种常见的数据结构,广泛应用于编程中。合并两个有序数组是LeetCode的经典问题之一,考察你对数组操作和排序算法的理解。在本文中,我们将详细探讨如何将两个有序数组合并为一个有序数组,并介绍多种合并方法,包括双指针法、归并法和内置函数法。同时,提供 Python 和 Java 代码示例,助你轻松理解和应用这些技巧。

  1. 双指针法
    双指针法是一种简单而有效的方法,它使用两个指针来分别遍历两个数组,并比较每个元素的大小。时间复杂度为 O(m+n),其中 m 和 n 分别是两个数组的长度。
def merge_sorted_arrays_two_pointers(nums1, nums2):
  """
  合并两个有序数组(双指针法)

  Args:
    nums1 (list): 第一个有序数组
    nums2 (list): 第二个有序数组

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

  # 检查数组是否为空
  if not nums1:
    return nums2
  if not nums2:
    return nums1

  # 创建合并后的数组
  merged_nums = []

  # 初始化两个指针
  i = 0
  j = 0

  # 比较两个数组的元素,并添加到合并后的数组中
  while i < len(nums1) and j < len(nums2):
    if nums1[i] < nums2[j]:
      merged_nums.append(nums1[i])
      i += 1
    else:
      merged_nums.append(nums2[j])
      j += 1

  # 将剩余的元素添加到合并后的数组中
  while i < len(nums1):
    merged_nums.append(nums1[i])
    i += 1

  while j < len(nums2):
    merged_nums.append(nums2[j])
    j += 1

  # 返回合并后的数组
  return merged_nums
import java.util.Arrays;

class MergeSortedArraysTwoPointers {

    public static int[] mergeSortedArrays(int[] nums1, int[] nums2) {
        // 检查数组是否为空
        if (nums1 == null || nums1.length == 0) {
            return nums2;
        }
        if (nums2 == null || nums2.length == 0) {
            return nums1;
        }

        // 创建合并后的数组
        int[] mergedNums = new int[nums1.length + nums2.length];

        // 初始化两个指针
        int i = 0;
        int j = 0;

        // 比较两个数组的元素,并添加到合并后的数组中
        while (i < nums1.length && j < nums2.length) {
            if (nums1[i] < nums2[j]) {
                mergedNums[i + j] = nums1[i];
                i++;
            } else {
                mergedNums[i + j] = nums2[j];
                j++;
            }
        }

        // 将剩余的元素添加到合并后的数组中
        while (i < nums1.length) {
            mergedNums[i + j] = nums1[i];
            i++;
        }

        while (j < nums2.length) {
            mergedNums[i + j] = nums2[j];
            j++;
        }

        // 返回合并后的数组
        return mergedNums;
    }

    public static void main(String[] args) {
        int[] nums1 = {1, 3, 5, 7};
        int[] nums2 = {2, 4, 6, 8};
        int[] mergedNums = mergeSortedArrays(nums1, nums2);
        System.out.println(Arrays.toString(mergedNums)); // 输出:[1, 2, 3, 4, 5, 6, 7, 8]
    }
}
  1. 归并法
    归并法是一种分治算法,它将两个数组分别拆分为较小的子数组,然后递归地合并这些子数组。时间复杂度为 O(m+n log(m+n)),其中 m 和 n 分别是两个数组的长度。
def merge_sorted_arrays_merge_sort(nums1, nums2):
  """
  合并两个有序数组(归并法)

  Args:
    nums1 (list): 第一个有序数组
    nums2 (list): 第二个有序数组

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

  # 检查数组是否为空
  if not nums1:
    return nums2
  if not nums2:
    return nums1

  # 将两个数组合并为一个数组
  merged_nums = nums1 + nums2

  # 对合并后的数组进行归并排序
  return merge_sort(merged_nums)


def merge_sort(nums):
  """
  归并排序

  Args:
    nums (list): 要排序的数组

  Returns:
    list: 排序后的数组
  """

  # 递归终止条件
  if len(nums) <= 1:
    return nums

  # 将数组拆分为两个子数组
  mid = len(nums) // 2
  left_nums = nums[:mid]
  right_nums = nums[mid:]

  # 递归排序两个子数组
  left_nums = merge_sort(left_nums)
  right_nums = merge_sort(right_nums)

  # 合并两个排序后的子数组
  return merge(left_nums, right_nums)


def merge(left_nums, right_nums):
  """
  合并两个排序后的数组

  Args:
    left_nums (list): 第一个排序后的数组
    right_nums (list): 第二个排序后的数组

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

  # 创建合并后的数组
  merged_nums = []

  # 初始化两个指针
  i = 0
  j = 0

  # 比较两个数组的元素,并添加到合并后的数组中
  while i < len(left_nums) and j < len(right_nums):
    if left_nums[i] < right_nums[j]:
      merged_nums.append(left_nums[i])
      i += 1
    else:
      merged_nums.append(right_nums[j])
      j += 1

  # 将剩余的元素添加到合并后的数组中
  while i < len(left_nums):
    merged_nums.append(left_nums[i])
    i += 1

  while j < len(right_nums):
    merged_nums.append(right_nums[j])
    j += 1

  # 返回合并后的数组
  return merged_nums
import java.util.Arrays;

class MergeSortedArraysMergeSort {

    public static int[] mergeSortedArrays(int[] nums1, int[] nums2) {
        // 检查数组是否为空
        if (nums1 == null || nums1.length == 0) {
            return nums2;
        }
        if (nums2 == null || nums2.length == 0) {
            return nums1;
        }

        // 将两个数组合并为一个数组
        int[] mergedNums = new int[nums1.length + nums2.length];

        // 对合并后的数组进行归并排序
        mergeSort(mergedNums, 0, nums1.length + nums2.length - 1);

        // 返回合并后的数组
        return mergedNums;
    }

    private static void mergeSort(int[] nums, int left, int right) {
        if (left < right) {
            int mid = left + (right - left) / 2;
            mergeSort(nums, left, mid);
            mergeSort(nums, mid + 1, right);
            merge(nums, left, mid, right);
        }
    }

    private static void merge(int[] nums, int left, int mid, int right) {
        int[] leftNums = Arrays.copyOfRange(