LeetCode题目15:三数之和
原题描述
+
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例
输入:[-1, 0, 1, 2, -1, 4]
输出:[[-1, 0, 1], [-1, -1, 2]]
原题链接:https://leetcode-cn.com/problems/3sum
思路解析
+
有印象的同学可能还记得,之前做过一道两数之和,思路还挺简单的。到了三数之和也别慌,至少三层循环暴力枚举是一定可以把这道题解出来的,但那样做就没什么意思了,我们还是思考有没有更优的思路吧~
假设在一个从小到大排好序的数组上做这道题,我们一定能够意识到一个基本事实:如果第 个数大于0,那么它没有任何机会和它后面的任意两个数相加为0,因为后面的数都是正数。
还是在排好序的数组上做这道题:如果第 个数不大于0,同时假设有另外两个可移动的指针分别放在了 之后,我们就假设是 和 ( )吧。有下面这么几种情况。
nums[i]+nums[j]+nums[k] > 0时,我们把 往左移是有机会让三个数之和向0靠近的。
反之,如果nums[i]+nums[j]+nums[k] < 0,我们右移 也是有机会让和向0靠近的。
所以我们只要固定一个 ,通过左右移动 和 就一定能够找到和为0的答案。但是去重是非常麻烦的,因为要分很多种情况讨论。
情况1——首先如果 和 的值相同,那么我们只需要其中选择一个位置继续搜索即可。因为后面 和 如果能和 配起来,那么也一定能和 配起来;
情况2——如果 和 的值相同,我们也能得到和情况1类似的结论;
情况3——如果 和 的值相同,同情况2。
所以碰到上面三种情况,直接跳过即可。所以这道题可以通过先排序,后用两个指针向中间不断移动的方法来解决。
复杂度分析
+
- 时间复杂度:
- 空间复杂度:
C++参考代码
+
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
if (nums.size() < 3) return res;
sort(nums.begin(), nums.end());
for (int i = 0; i < nums.size() - 2; ++i) {
if (nums[i] > 0) break;
else if (i > 0 && nums[i] == nums[i-1]) continue;
else {
int l = i + 1;
int r = nums.size() - 1;
while (l < r) {
if (nums[i] + nums[l] + nums[r] == 0) {
res.push_back({nums[i], nums[l], nums[r]});
while (l < r && (nums[l] == nums[l + 1])) ++l;
while (l < r && (nums[r] == nums[r - 1])) --r;
++l; --r;
}
else if (nums[i] + nums[l] + nums[r] > 0) --r;
else ++l;
}
}
}
return res;
}
};
- windows API 开发飞机订票系统 图形化界面 (二)
- SQL SERVER几种数据迁移/导出导入的实践
- dom4j 使用总结
- 快速对表的某字段赋递增的数值
- SQL SERVER修改函数名引起的问题
- SQL Server安全(1/11):SQL Server安全概述
- SQL Server安全(2/11):身份验证(Authentication)
- SQL Server安全(3/11):主体和安全对象(Principals and Securables)
- 在SQL Server里如何进行页级别的恢复
- 你可能不知道的字符比较中的“秘密”
- c++实现简单计算器
- re模块(正则表达式)
- Python学习——collections系列
- 为stackGan一个工程创建一个虚拟环境,python 2.7 tensorflow0.12-tensorflow 1.01
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 关于一些技术点的随笔记录(二)
- 快速排序与三路快速排序
- 垃圾回收器 Krains 2020-08-07
- OWIN 请求处理与中间件
- 关于Spring AOP,除了动态代理、CGLIB,你还知道什么?
- elasticSearch学习(三)
- 挑苹果中的行为参数化思想
- 详解MapReduce(Spark和MapReduce对比铺垫篇)
- 使用 OWIN 作为 ASP.NET Web API 的宿主
- 二进制源码和补码的基础解释
- Spark推荐系统实践
- Xamarin Studio 比 Visual Studio 2013 好用的三个功能
- Scss (Sass) 语法简介
- 如何写一个简单的node.js c++扩展
- 给 c# 程序员的十个重要提示