返回
LeetCode.88 合并两个有序数组,合并有序数组技巧全方位解析
闲谈
2023-11-27 20:10:04
数组作为一种常见的数据结构,广泛应用于编程中。合并两个有序数组是LeetCode的经典问题之一,考察你对数组操作和排序算法的理解。在本文中,我们将详细探讨如何将两个有序数组合并为一个有序数组,并介绍多种合并方法,包括双指针法、归并法和内置函数法。同时,提供 Python 和 Java 代码示例,助你轻松理解和应用这些技巧。
- 双指针法
双指针法是一种简单而有效的方法,它使用两个指针来分别遍历两个数组,并比较每个元素的大小。时间复杂度为 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]
}
}
- 归并法
归并法是一种分治算法,它将两个数组分别拆分为较小的子数组,然后递归地合并这些子数组。时间复杂度为 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(