[230420 leetcode15] 三数之和
题目描述
原题链接
给你一个整数数组 nums
,判断是否存在三元组 [nums[i], nums[j], nums[k]]
满足 i != j
、i != k
且 j != k
,同时还满足 nums[i] + nums[j] + nums[k] == 0
。请
你返回所有和为 0
且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。
示例 2:
输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。
示例 3:
输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。
解题思路
1. 初步分析
要找三元组,最原始最暴力的方法就是三层遍历,时间复杂度 O(n^3)。但就像双指针可以把二维遍历降为一维遍历一样,使用双指针也可以把三维遍历降为二维的。
2. 三指针解法
基本思路:
- 使用三个指针 i、j、k,i 指针指示三元组的第一个数,j 指针和 k 指针相向移动,分别指向三元组的第二个数和第三个数。
- 对 nums[i]、nums[j]、nums[k] 求和,根据 sum 值大小进行讨论
- 等于 0:放入结果数组,j、k 同时移动
- 小于 0:移动 j
- 大于 0:移动 k
去重逻辑:
i 位去重
//检查下标合法 && 当前i位与前一个i位(nums[i-1])相等 if(i > 0 && nums[i] == nums[i - 1]){continue; }
j 位去重
//检查下标合法 && 当前j位与前一个j位(nums[j-1])相等 if(j > i + 1 && nums[j] == nums[j - 1]){++j;continue; }
k 位去重(k 是从右向左移动的)
//检查下标合法 && 当前k位与前一个k位(nums[k+1])相等 if(k < nums.size() - 1 && nums[k] == nums[k + 1]){--k;continue; }
**剪枝逻辑:**核心算法前对数组进行排序,若三元组第三位(即 k 位)元素大于 0,则可跳出当前双指针循环。
3. 代码主干
vector<vector<int>> threeSum(vector<int>& nums) {vector<vector<int>> result;sort(nums.begin(), nums.end());//遍历i位for(int i = 0; i < nums.size() - 2; ++i){//对i为进行去重//定义j、k指针int j = i + 1, k = nums.size() - 1;while(j < k){ //利用双指针降维//剪枝//对j位进行去重//对k位进行去重//计算sum值,并对sum值进行讨论}}return result;
}
完整代码
vector<vector<int>> threeSum(vector<int>& nums) {vector<vector<int>> result;sort(nums.begin(), nums.end());for(int i = 0; i < nums.size() - 2; ++i){//对i为进行去重if(i > 0 && nums[i] == nums[i - 1]){continue;}int j = i + 1, k = nums.size() - 1;while(j < k){ //利用双指针降维//剪枝if(nums[k] < 0) break;//对j位进行去重if(j > i + 1 && nums[j] == nums[j - 1]){++j;continue;}//对k位进行去重if(k < nums.size() - 1 && nums[k] == nums[k + 1]){--k;continue;}//计算sum值,并对sum值进行讨论int sum = nums[i] + nums[j] + nums[k];if(sum == 0){vector<int> tmp = {nums[i], nums[j], nums[k]};result.push_back(tmp);++j, --k;}else if(sum < 0){++j;}else if(sum > 0){--k;}}}return result;
}
关于 unordered_set 的补充
在尝试优化时浅浅使用了一下 unordered_set<vector<int>>
,编译报错:
Line 6: Char 36: error: call to implicitly-deleted default constructor of 'unordered_set<vector<int>>'unordered_set<vector<int>> result;
搜索了一下 unordered_set 的使用方法,发现 unordered_set 容器的类模板定义如下:
template < class Key, //容器中存储元素的类型class Hash = hash<Key>, //确定元素存储位置所用的哈希函数class Pred = equal_to<Key>, //判断各个元素是否相等所用的函数class Alloc = allocator<Key> //指定分配器对象的类型> class unordered_set;
逐个分析:
- **容器中存储元素的类型:**在 unordered_set 中,key 和 value 的类型都是一致的,指的就是 key 的类型
- **确定元素存储位置所用的哈希函数:**指定元素存储位置的哈希函数,注意:默认哈希函数 hash<Key> 只适用于基本数据类型(包括 string 类型),而不适用于自定义的结构体或者类。比如说 vector<int> 不属于基本数据类型。
- **判断各个元素是否相等所用的函数:**unordered_set 容器内部不能存储相等的元素,而衡量 2 个元素是否相等的标准,取决于该参数指定的函数。 默认情况下,使用 STL 标准库中提供的 equal_to<key> 规则,该规则仅支持可直接用 == 运算符做比较的数据类型。
- 指定分配器对象的类型:略
[230420 leetcode15] 三数之和相关推荐
- LeetCode15. 三数之和 16. 最接近的三数之和
LeetCode15. 三数之和 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组 ...
- [Swift]LeetCode15. 三数之和 | 3Sum
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ ➤微信公众号:山青咏芝(shanqingyongzhi) ➤博客园地址:山青咏芝(https://www.cnblog ...
- leetcode15. 三数之和(三指针)
一:题目 二:思路 1.这里的去重是指的是我们在遍历元素的时候,遇到相同的挨着的相同的元素的时候要跳过 2.对元素进行排序,为了后面的比较 3.我们用的是三个指针,第一个指针i指向第一个元素,第二个指 ...
- leetcode15 三数之和
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以包含重复的三元组. ...
- leetcode15. 三数之和(详解)
一:题目 二:上码 class Solution {public:/**思路:1.这个题出其不意之处在于,其先对这个序列进行了排序排序的好处是1>:如果首元素是大于0的,那么如果无论无何也凑不出 ...
- Leetcode--15. 三数之和
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以包含重复的三元组. ...
- LeetCode--15.三数之和
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j.i != k 且 j != k ,同时还满足 nums[i] + nums ...
- 【LeetCode15】三数之和
三数之和 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组. 注意:答案中不可以包含 ...
- LeetCode 15. 三数之和(3Sum)
15. 三数之和 15. 3Sum 题目描述 Given an array nums of n integers, are there elements a, b, c in nums such th ...
最新文章
- 自动驾驶平台,阵营, 主要传感器与场景联系
- 依赖类型dependency type在maven中的作用
- onethink封装arclist调用文章列表!
- 2013年国家计算机一级考试试题,2013年计算机一级的考试试题.doc
- Spring Boot –现代Java应用程序的基础
- 基于matlab的ldpc编码的构造,基于LDPC编码的GMSK调制与解调及matlab仿真实现(含录像)...
- css 多栏文字流 css two columns text flow
- PHP特级课视频教程_第三十四集 Mongodb性能优化_李强强
- 29.Linux/Unix 系统编程手册(上) -- 线程:介绍
- DSP28335定时器
- 20210422-微信刷脸支付获取调用凭证authinfo的时候,提示 rawdata无效
- WIN10_用户获取最高的管理员权限(关闭UAC控制)
- Layabox 屏幕适配
- HttpHeaders()无法调用
- 《单片机原理及应用(魏洪磊)》第七章第8题
- 【JZOJ4598】准备食物
- 网易企业邮箱:三道防御、七项措施,切实保障企业邮箱安全【企业邮箱申请】
- Oracle数据库实例之内存架构(一)
- 千年服务器经验怎么修改,千年服务端加入江湖等级的脚本
- 高新技术企业申请容易吗?如何提高申报通过的机率?