三和问题,二和问题头条爱考
三和问题用了二和的核心代码。
本准备回去写写二和,写完发现答案不对,没那么简单。题目让返回的是两数的下标,这样的话,排序之后下标就乱了。看了Solutoin、Discuss和百度的答案,几乎都是用哈希表来把搜索第二个数的复杂度从 O (n)降到O(1)。再有就是sort+自己设定一个类来存值与下标的映射,或者复制了一遍原数组,再遍历一次找出来它的原下标这些不那么优雅的方法。反正还是hash比较强大和优雅,遍历一次就行,回头研究研究哈希吧。
回到三和问题。要求的不是返回下标,是返回符合要求的数就行,这就好办了。但也遇到了一些问题:
答案中有重复:去修改
改完当前测试用例过了,就提交,发现溢出了。leetcode就是好,告诉了最后运行的case是[0, 0, 0],简直是oj中的黑匣子啊!对着这个case手动运行代码,发现是因为刚才避免重复的时候引入了新bug。增减迭代时候没控制好条件,它就放飞自我了。
改完后通过,代码如下:
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> result;
int length = nums.size();
if(length < 3) return result;
sort(nums.begin(), nums.end());
for(int i=0; i<length-2; i++) {
if(i!=0 && nums[i] == nums[i-1]) continue; // 避免重复
int target = 0 - nums[i];
int j=i+1, k=length-1;
int current;
while(j<k) {
current = nums[j] + nums[k];
if(current == target) {
vector<int> temp{nums[i], nums[j], nums[k]};
result.push_back(temp);
do {
j++;
} while (nums[j] == nums[j-1] && j<k);
do{
k--;
} while (nums[k] == nums[k+1] && k>j);
} else if(current < target) {
j++;
} else {
k--;
}
}
}
return result;
}
};
另外我突然发现,和vector绝配的是iterator,会使代码变简洁,下次code有余力时候试试吧。
另外表扬一下一年半之前的自己,用js写的,虽然复杂度高,但是代码那叫一个简洁 ……^ _ ^