双指针法合并升序数组需预分配目标数组空间,用i、j、k三指针分别遍历两输入数组和结果数组,循环比较元素大小并赋值,最后处理剩余元素,避免越界与覆盖。

合并两个升序数组的双指针法最可靠
直接用 std::merge 最省事,但多数面试或手写场景要求自己实现——核心就是双指针从头开始比对,谁小谁进结果数组。关键不是“能不能做”,而是避免越界、漏元素、覆盖原数组。
- 必须预分配足够空间的目标数组(如
vector<int> res(a.size() + b.size())</int>),不能边 push_back 边比较,否则无法保证 O(1) 额外空间(若允许额外空间则可接受) - 三个下标变量:i 指向数组 a,j 指向数组 b,k 指向结果数组;循环条件是
i ,之后要分别收尾剩余部分 - 常见错误是把收尾写成
while (i 却忘了 <code>k初始值已变,或漏掉j的剩余段
std::merge 要注意迭代器和目标容器容量
std::merge 是标准解法,但一不留神就崩溃。它不自动扩容,只按你给的迭代器范围写入——目标容器必须已有足够空间,或用 back_inserter 配合 vector。
- 安全写法:
vector<int> res; res.reserve(a.size() + b.size()); merge(a.begin(), a.end(), b.begin(), b.end(), back_inserter(res));</int> - 危险写法:
vector<int> res; merge(a.begin(), a.end(), b.begin(), b.end(), res.begin());</int>——res为空,res.begin()无效,触发未定义行为 - 如果目标是原地合并到其中一个数组(如把 b 合并进 a),需确保 a 容量足够,且从后往前填,避免覆盖未处理元素
降序数组合并只需改比较方向
升序是 a[i] 时取 a[i],降序反过来:只要 <code>a[i] >= b[j] 就取 a[i]。逻辑完全一致,只是大小判断翻转,别硬套升序模板。
- 输入为降序时,别先 reverse 再 merge 再 reverse——多两次 O(n) 操作,纯属浪费
- 若混用升序和降序数组(比如 a 升序、b 降序),先统一方向(reverse 一个),再 merge,比写混合逻辑更清晰、少出错
- STL 的
std::merge默认升序,要合并降序数组,得传自定义比较器:merge(a.rbegin(), a.rend(), b.rbegin(), b.rend(), res.rbegin(), greater<int>())</int>
原地合并到较长数组末尾要反向填充
LeetCode 88 那类题要求把 nums2 合并进 nums1,且 nums1 末尾有足够空位。这时必须从后往前填,否则会覆盖 nums1 前面还没读的数。
- 设 i = m-1(nums1 有效末尾),j = n-1(nums2 末尾),k = m+n-1(nums1 总末尾);每次比较
nums1[i]和nums2[j],大者填入nums1[k] - 边界处理:当 i
- 容易忽略的是:即使 j ≥ 0,也要在循环结束后补一句
while (j >= 0) nums1[k--] = nums2[j--];,否则 nums2 剩余元素丢了
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











