news 2026/10/29 11:01:34

【算法拾光】双指针|两数之和 II - 输入有序数组 + 三数之和

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【算法拾光】双指针|两数之和 II - 输入有序数组 + 三数之和

题目 1:两数之和 II - 输入有序数组

链接:167. 两数之和 II - 输入有序数组 - 力扣(LeetCode)

题目分析

给你一个下标从 1 开始的整数数组 numbers,该数组已按非递减顺序排列。请你从数组中找出满足相加之和等于目标数 target 的两个数。返回这两个数对应的下标(下标从 1 开始),且每个输入只有一个答案,不能重复使用同一个元素。 例:numbers = [2,7,11,15], target = 9,答案[1,2]。 核心:数组有序 + 唯一解,适合用相向双指针,左右两端夹逼,O (n) 解决,比哈希表更省空间、更能体现有序价值。

算法原理

利用有序数组「两端夹逼」的单调性:

  1. 左指针left = 0,右指针right = n-1
  2. 计算sum = numbers[left] + numbers[right]
    • sum == target:找到答案,返回[left+1, right+1]
    • sum < target:和太小,需要更大的数,左指针右移 →left++
    • sum > target:和太大,需要更小的数,右指针左移 →right--
  3. 直到left >= right结束

为什么可行?数组有序,左指针右移一定让和变大,右指针左移一定让和变小,两个指针只能单向移动,保证不会漏解。

代码编写

vector<int> twoSum(vector<int>& numbers, int target) { int left = 0, right = numbers.size() - 1; while(left < right) { int sum = numbers[left] + numbers[right]; if(sum == target) { return {left + 1, right + 1}; } else if(sum < target) { left++; } else { right--; } } return {-1, -1}; }

总结

相向双指针最基础的模板:有序数组两端夹逼,和太小动左、和太大动右。O (n) 时间、O (1) 空间,是后续三数之和、接雨水等题的基础。


题目 2:三数之和

链接:15. 三数之和 - 力扣(LeetCode)

题目分析

给你一个整数数组 nums,判断是否存在三元组[nums[i], nums[j], nums[k]]满足i != j、j != k 且 i != k,同时还满足nums[i] + nums[j] + nums[k] == 0。请返回所有和为 0 且不重复的三元组。 例:nums = [-1,0,1,2,-1,-4],答案[[-1,-1,2],[-1,0,1]]。 核心:暴力 O (n³) 超时,排序后固定一个数,再用相向双指针找剩下两数,可降到 O (n²)。难点在于去重:既要避免同一元素重复使用,又要保证答案三元组不重复。

算法原理

排序 + 固定一个数 + 双指针夹逼,核心步骤:

  1. 先对 nums 排序(有序才能用双指针,也方便去重)
  2. 外层循环固定第一个数nums[i]:
    • 去重:若i > 0且nums[i] == nums[i-1],跳过(同一数值只作为第一个数一次)
    • 设目标target = -nums[i],用双指针在[i+1, n-1]里找两数之和等于 target
  3. 内层相向双指针left = i+1, right = n-1:
    • sum = nums[left] + nums[right]
    • sum == target:记录三元组,然后双指针同时去重(跳过重复的 left 和 right),再收缩
    • sum < target:left++
    • sum > target:right--
  4. 剪枝:nums[i] > 0时后面全是正数,直接 break

去重是本题灵魂:固定数去重 + 找到答案后左右指针去重,三处去重缺一不可。

代码编写

vector<vector<int>> threeSum(vector<int>& nums) { vector<vector<int>> res; sort(nums.begin(), nums.end()); int n = nums.size(); for(int i = 0; i < n - 2; i++) { if(nums[i] > 0) break; // 剪枝:首项>0后面全正 if(i > 0 && nums[i] == nums[i - 1]) continue; // 去重固定数 int target = -nums[i]; int left = i + 1, right = n - 1; while(left < right) { int sum = nums[left] + nums[right]; if(sum == target) { res.push_back({nums[i], nums[left], nums[right]}); while(left < right && nums[left] == nums[left + 1]) left++; // 去重左 while(left < right && nums[right] == nums[right - 1]) right--; // 去重右 left++; right--; } else if(sum < target) { left++; } else { right--; } } } return res; }

总结

三数之和 =排序 + 固定一个 + 相向双指针,O (n²)。三个去重点(固定数、找到答案后的左右指针)是防重复的关键。它是「两数之和 II」的进阶,也是面试中出现频率极高的经典题。


本篇总结

本篇进入双指针系列,核心是相向双指针(有序数组两端夹逼):

  1. 两数之和 II:最简相向双指针,和的大小驱动指针单向移动
  2. 三数之和:排序后固定一个数,转成两数之和,难点是三层去重

相向双指针的价值:把有序数组的 O (n²) 暴力降到 O (n),本质是利用「单调性」排除不可能的组合。下一篇可以安排同类型进阶:最接近的三数之和 / 四数之和,或容器盛水最多的水 / 接雨水。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/29 10:59:28

Agent开发:普通人逆袭高薪赛道,错过等三年!收藏必备

Agent开发是未来3年最值得普通人冲的技术岗&#xff0c;门槛可控&#xff0c;缺口极大&#xff0c;薪资断层领先&#xff0c;且不被AI替代。它不同于传统的AI岗位&#xff0c;而是应用层落地的智能体开发&#xff0c;核心是让AI自主思考、拆解任务、调用工具&#xff0c;完成完…

作者头像 李华
网站建设 2026/10/29 10:59:11

Agent评测可落地体系

Agent评测可落地体系&#xff1a;方法、步骤与工具 以下内容对齐阿里、腾讯、字节、百度等大厂公开的Agent评测方法论与开源工具链&#xff0c;全部为可直接落地的工程化方案&#xff0c;而非纯学术理论。 一、核心评测方法论&#xff08;四层全链路范式&#xff09; 大厂普…

作者头像 李华
网站建设 2026/10/29 10:57:36

Beyond Single‑Model Injection 论文总结

> 说明:arXiv摘要页面只公开**Abstract**,未直接提供 Introduction、Conclusion 完整文本;公开的网页摘要仅能拿到Abstract原文。下面完成:文章概要、创新点、Abstract中英对照;并标注Introduction/Conclusion获取方式。输出完整Markdown文档。 # Beyond Single‑Mode…

作者头像 李华
网站建设 2026/10/29 10:57:13

一个开源的轻量级agent框架

干货推荐人&#xff1a;&#xff0c;学习者简介关于这个agere, 它是一个开源的属于agent方面的轻量级的框架。这个框架的主要特点就在于通用性强, 而且具有完全的可定制性。它是通过把复杂的流程进行拆解, 拆分成一系列独立的、小的步骤, 以此来简化构建那种具有复杂逻辑的agen…

作者头像 李华
网站建设 2026/10/29 10:57:11

Python 零基础合辑⑦:input 输入(让程序和你对话)

大家好, 接上一篇的合辑内容, 具体来说是第⑥篇的内容, 那一篇里我们学会了数字计算, 所以今天我们来学习名为input的输入功能, 这个知识点是非常有趣的, 属于最有趣的知识点之一。要是你学会了它, 就可以做出可以跟人互动的程序, 往里面输入名字、年龄以及数字, 电脑就会自动作…

作者头像 李华