LeetCode 第 88 题是“合并两个有序数组”。题目要求将两个有序数组合并为一个有序数组,假设第一个数组有足够的空间来容纳第二个数组的所有元素。
以下是该题目的 Java 解答,并对每行进行详细注释:
public class MergeSortedArray {
// 主方法用于测试合并功能
public static void main(String[] args) {
int[] nums1 = {1, 2, 3, 0, 0, 0}; // 第一个数组,容量为m + n
int m = 3; // 第一个数组的有效元素数
int[] nums2 = {2, 5, 6}; // 第二个数组
int n = 3; // 第二个数组的元素数
merge(nums1, m, nums2, n); // 调用合并方法
for (int num : nums1) {
System.out.print(num + " "); // 打印合并后的数组
}
}
// 合并两个有序数组的方法
public static void merge(int[] nums1, int m, int[] nums2, int n) {
int i = m - 1; // nums1的最后一个有效元素的索引
int j = n - 1; // nums2的最后一个元素的索引
int k = m + n - 1; // 合并后数组的最后一个位置的索引
// 从后向前合并数组
while (i >= 0 && j >= 0) { // 只要两个数组都有元素未处理
if (nums1[i] > nums2[j]) { // 如果nums1的当前元素大于nums2的当前元素
nums1[k] = nums1[i]; // 把nums1的当前元素放到合并位置
i--; // 移动nums1的指针
} else { // 如果nums2的当前元素大于等于nums1的当前元素
nums1[k] = nums2[j]; // 把nums2的当前元素放到合并位置
j--; // 移动nums2的指针
}
k--; // 移动合并位置的指针
}
// 如果nums2还有剩余元素,直接拷贝到nums1的开头
while (j >= 0) {
nums1[k] = nums2[j]; // 拷贝nums2的元素到nums1
j--; // 移动nums2的指针
k--; // 移动合并位置的指针
}
}
}
代码说明:
-
变量初始化:
i = m - 1
:指向nums1
有效元素的最后一个位置。j = n - 1
:指向nums2
的最后一个位置。k = m + n - 1
:指向合并后数组的最后一个位置。
-
合并过程:
- 使用
while
循环从后向前合并两个数组,比较nums1
和nums2
的当前元素,将较大的元素放到nums1
的最后面。 - 如果
nums1[i] > nums2[j]
,将nums1[i]
放到nums1[k]
,然后递减i
和k
。 - 否则,将
nums2[j]
放到nums1[k]
,递减j
和k
。
- 使用
-
剩余元素处理:
- 如果
nums2
还有剩余元素(即j >= 0
),将这些元素直接拷贝到nums1
开头,因为nums1
的剩余元素已经在合适位置上。
- 如果
这段代码能有效地将两个有序数组合并成一个有序数组。