力扣-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;
}
};
麻烦的是去重
标签:15,nums,三数,元素,力扣,secondIndex,数组,firstNum,thirdIndex 来源: https://www.cnblogs.com/yaocy/p/16591916.html