力扣-15-三数之和
直达链接
前两天刚做了梦开始的地方两数之和
常规思路是二层遍历,对于每个数都去遍历数组找有没有刚好能凑成指定数字的
进阶思路是使用hashmap,一次遍历,对于每个元素去看hahsmap里有没有能凑成一对的,有就直接返回(因为题设答案唯一),没有就插到hashmap里面去(键为值,值为索引位置)
题目要求不重复,那么其实也可以说i<j<k,即定义返回数组的下标是递增的
这让我想到了之前拿回溯做题,去重也这么干过
感觉这里确实可以这么干,写一个回溯函数,定义一个int参数值为上一个选中元素的下标,当前元素下标大于才能被选中,然后和满足题目要求就放入结果数组
但其实这么找出来的原始序列是有重复的……有时间回过头去看一下是怎么写的
标签是:“数组”“双指针”“排序”…没有回溯
双指针应该才是正解,我是直接写了个三重循环出来之前,但是好像不对
提示1说可以固定一个元素,然后剩下的就可以用两数之和去解决,但是感觉不太好
我看题解里说要数组元素a<=b<=c,这样你还要排个序,然后又说元素大小不能一样…何必呢
用数组下标不香吗,好吧,也要考虑元素大小不能一样,还真就不香了
看完亮点思路应该是把三重循环变成了一重循环+双指针,但其实能这么做首先是因为题目“求和”的设定,另外,前面用了sort()
排过一遍序的原因
思路理解没问题了,但是感觉跟那边的【三元组】还是有比较大不同的,那边强制要求了下标
class Solution { public: vector<vector<int>> threeSum(vector<int>& nums) { if (nums.size() < 3) return {}; vector<vector<int>> ret; sort(nums.begin(), nums.end()); for (int firstNum = 0; firstNum < nums.size() - 2; ++firstNum) { // 如果排序后的第一个元素就大于0,后面不用看了,但是之前已经放入结果数组中的要算 if (nums[firstNum] > 0) return ret; if (firstNum > 0 && nums[firstNum] == nums[firstNum - 1]) continue; int secondIndex = firstNum + 1, thirdIndex = nums.size() - 1; while (secondIndex < thirdIndex) { // 前两个判断语句是为了不等,但是不需要同时移动 if (nums[secondIndex] + nums[thirdIndex] > -nums[firstNum]) thirdIndex--; else if (nums[secondIndex] + nums[thirdIndex] < -nums[firstNum]) secondIndex++; else { ret.push_back({ nums[firstNum],nums[secondIndex],nums[thirdIndex] }); secondIndex++; thirdIndex--; // 例如:[-4,1,1,1,2,3,3,3], i=0, left=1, right=5 // 上面各自加减了一次,所以不会越界 while (secondIndex < thirdIndex && nums[secondIndex] == nums[secondIndex - 1]) secondIndex++; while (secondIndex < thirdIndex && nums[thirdIndex] == nums[thirdIndex + 1]) thirdIndex--; } } } return ret; } };
麻烦的是去重
本文作者:YaosGHC
本文链接:https://www.cnblogs.com/yaocy/p/16591916.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步