题目描述:
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
例如,给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[ [-1, 0, 1], [-1, -1, 2] ]
方法一:哈希表
想法类似于两数之和,在本题中,已知前两个数,查找数组中是否存在-a-b
#include<iostream> #include<vector> #include<unordered_map> #include<algorithm> using namespace std; class Solution{ public: vector<vector<int>> threeSum(vector<int>& nums){ vector<vector<int>> result; if(nums.size() == 0) return result; sort(nums.begin(), nums.end()); //对数组排序是为了后续去重 for(int i=0; i<nums.size(); ++i){ if(i!=0 && nums[i] == nums[i-1]) continue; unordered_map<int, int> map; for(int j=i+1; j<nums.size(); ++j){ if(map.find(-nums[i]-nums[j]) != map.end()){ result.push_back({nums[i], nums[j], -nums[i]-nums[j]}); while(j+1 < nums.size() && nums[j] == nums[j+1]) j++; } map.insert({nums[j], j}); } } return result; } }; int main(){ Solution solution; vector<int> vec; int i; do{ cin>>i; vec.push_back(i); }while(getchar() != '\n'); vector<vector<int>> result; result = solution.threeSum(vec); int rows = result.size(); int columns = result[0].size(); for(int i=0; i<rows; ++i) for(int j = 0; j<columns; ++j){ cout<<result[i][j]<<" "; } cout<<endl; return 0; }
方法一最后两个测试用例没有通过,超出时间限制
方法二:双指针法
首先必须对数组排序,排序后才能使用双指针。遍历整个数组,用i指向a所在的位置,然后固定a,用两个指针指向b和c。移动b和c的位置,直至找到a+b+c=0
//双指针 class Solution{ public: vector<vector<int>> threeSum(vector<int>& nums){ vector<vector<int>> result; if(nums.size() == 0) return result; sort(nums.begin(), nums.end()); for(int i=0; i<nums.size(); ++i){ if(i!=0 && nums[i-1]== nums[i]) //去重 continue; int j = i+1; int k = nums.size()-1; while(j < k){ if(nums[i] + nums[j] + nums[k] == 0){ result.push_back({nums[i], nums[j], nums[k]}); j++; k--; while(j<k && nums[j-1] == nums[j]) //去重 j++; while(j<k && nums[k+1] == nums[k]) //去重 k--; } else if(nums[i] + nums[j] +nums[k] < 0) j++; else k--; } } return result; } };