1. 合并两个有序数组
给你两个按 非递减顺序 排列的整数数组 nums1
和 nums2
,另有两个整数 m
和 n
,分别表示 nums1
和 nums2
中的元素数目。
请你 合并 nums2
到 nums1
中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1
中。为了应对这种情况,nums1
的初始长度为 m + n
,其中前 m
个元素表示应合并的元素,后 n
个元素为 0
,应忽略。nums2
的长度为 n
。
示例 1:
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3 输出:[1,2,2,3,5,6] 解释:需要合并 [1,2,3] 和 [2,5,6] 。 合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。
示例 2:
输入:nums1 = [1], m = 1, nums2 = [], n = 0 输出:[1] 解释:需要合并 [1] 和 [] 。 合并结果是 [1] 。
示例 3:
输入:nums1 = [0], m = 0, nums2 = [1], n = 1 输出:[1] 解释:需要合并的数组是 [] 和 [1] 。 合并结果是 [1] 。 注意,因为 m = 0 ,所以 nums1 中没有元素。nums1 中仅存的 0 仅仅是为了确保合并结果可以顺利存放到 nums1 中。
提示:
nums1.length == m + n
nums2.length == n
0 <= m, n <= 200
1 <= m + n <= 200
-109 <= nums1[i], nums2[j] <= 109
2. 解题思路
由题目可知nums[1]和nums[2]是两个非递减顺序 排列的整数数组,所以可以利用了两个输入数组已经有序的特性,采用双指针的方法,通过比较当前指针所指的元素大小来决定下一个要放入
sorted
的元素,从而保持合并后的数组有序。
初始化:首先,定义两个指针
p1
和p2
,分别初始化为指向nums1
和nums2
的起始位置。同时,创建一个大小为m + n
的数组sorted
,用于临时存储合并后的结果。合并过程:使用一个
while
循环来处理合并过程。循环的条件是p1 < m
或p2 < n
,即至少有一个数组还有未处理的元素。在循环内部,根据以下情况选择下一个要放入sorted
的元素:
- 如果
p1
已经到达nums1
的末尾(即p1 == m
),则将nums2
的下一个元素放入sorted
。- 如果
p2
已经到达nums2
的末尾(即p2 == n
),则将nums1
的下一个元素放入sorted
。- 如果
nums1[p1]
小于nums2[p2]
,则将nums1[p1]
放入sorted
,并移动p1
。- 否则,将
nums2[p2]
放入sorted
,并移动p2
。放置元素:每次选定一个元素后,将其放置在
sorted
数组中p1 + p2 - 1
的位置。这是因为p1
和p2
分别代表了nums1
和nums2
中已经处理过的元素数量,p1 + p2 - 1
就是当前合并元素在sorted
中的正确位置。复制回
nums1
:当sorted
数组填满后,使用一个for
循环将sorted
中的所有元素复制回nums1
。这样,nums1
就包含了合并后的有序数组。
// 定义 merge 函数,接收六个参数:两个数组的指针、大小和元素数量
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
int p1 = 0, p2 = 0; // 初始化两个指针,分别指向 nums1 和 nums2 的起始位置
int sorted[m + n]; // 创建一个新数组 sorted,用于存储合并后的结果
int cur; // 临时变量,用于存储当前要插入的元素
while (p1 < m || p2 < n) { // 当两个数组中还有未合并的元素时,继续执行
if (p1 == m) { // 如果 nums1 已经合并完毕,剩下的元素都来自 nums2
cur = nums2[p2++];
} else if (p2 == n) { // 如果 nums2 已经合并完毕,剩下的元素都来自 nums1
cur = nums1[p1++];
} else if (nums1[p1] < nums2[p2]) { // 如果当前 nums1 的元素小于 nums2 的元素
cur = nums1[p1];
p1++; // 移动 nums1 的指针
} else { // 如果当前 nums2 的元素小于或等于 nums1 的元素
cur = nums2[p2];
p2++; // 移动 nums2 的指针
}
sorted[p1 + p2 - 1] = cur; // 将当前要插入的元素放到 sorted 数组的正确位置
}
for (int i = 0; i != m + n; ++i) { // 将 sorted 数组的内容复制回 nums1
nums1[i] = sorted[i];
}
}