算法-哈希表:三数之和
在一个数组中,找到三个元素(这三个元素就是一个三元组),使其相加等于0,这个数组中可以找到多少组这样的元组?输出这些三元组。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//本题使用哈希解法不太合适,通过两次for确定a和b的值,然后采用哈希法确定数组中是否出现(0-(a+b)),可行但去重非常麻烦。
//采用双指针解法,对数组进行排序,通过一次for循环,left为i后的第一个值,right为最后一个值,求和,若大于0,则right--,若小于0,则left++
vector<vector<int>> forSum(vector<int> nums){
vector<vector<int>> result;
sort(nums.begin(), nums.end());
if(nums.size() > 0){
if(nums[0] > 0){ //剪枝:排序之后第一个元素大于0,则一定不会出现满足条件的三元组
return result;
}
}
for(int i = 0; i < nums.size(); i++){
//首先对i进行去重,i为0的时候不考虑,因为第0个肯定要参与比较
if(i > 0 && nums[i] == nums[i-1]){
continue;
}
//定义left和right
int left = i+1;
int right = nums.size()-1;
while (left < right){
if(nums[i]+nums[left]+nums[right]>0) {
right--;
}
else if(nums[i]+nums[left]+nums[right]<0) {
left++;
}
else {
result.push_back(vector<int>{nums[i],nums[left],nums[right]});
//去重。去重要在三元组有值之后再判定,不然会忽略[0,0,0]的情况
while(left < right && nums[left] == nums[left+1]){
left++;
}
while(left < right && nums[right] == nums[right-1]){
right--;
}
//找到答案之后,记得同时收缩指针!!!只收缩一个是不可能满足和为0这个条件的
right--;
left++;
}
}
}
return result;
}
int main() {
vector<int> nums1 = {-1,3,4,-3,0,-1,3,-3};
vector<vector<int>> result = forSum(nums1);
for(int i = 0; i < result.size(); i++){
for(int j = 0; j < result[i].size(); j++){
cout<< result[i][j]<<" ";
}
cout<<endl;
}
return 0;
}
输出结果为:
-3 -1 4
-3 0 3