2022-08-17 23:17阅读: 23评论: 0推荐: 0

力扣-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 中国大陆许可协议进行许可。

posted @   YaosGHC  阅读(23)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起