题目:
暴力方法:
class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {vector<vector<int>> res;std::unordered_set<std::string> uniqueValues;//保证结果唯一for(int i=0;i<nums.size();i++){//三个值暴力求解for(int j=0;j<nums.size();j++){for(int k=0;k<nums.size();k++){if(i!=j && i!=k && j!=k && nums[i]+nums[j]+nums[k]==0){vector<int> temp;temp.push_back(nums[i]);temp.push_back(nums[j]);temp.push_back(nums[k]);sort(temp.begin(),temp.end());//排序ostringstream oss;oss<<temp[0]<<temp[1]<<temp[2];std::string temposs=oss.str();//cout<<oss.str()<<endl;// for(const auto & elem:uniqueValues){// cout<<"---"<<elem<<endl;// }if(uniqueValues.find(temposs)!=uniqueValues.end()){//结果去重//cout<<temposs<<endl;}else{uniqueValues.insert(temposs);res.push_back(temp);}}}}}return res;}
};
优化方法1:
class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {vector<vector<int>> res;std::unordered_set<std::string> uniqueValues;//保证结果唯一std::unordered_map<std::string,vector<int>>uniqueKVs;for(int i=0;i<nums.size();i++){//优化下,选择二个for(int j=i+1;j<nums.size();j++){vector<int> temp;temp.push_back(nums[i]);temp.push_back(nums[j]);temp.push_back(0-(nums[i]+nums[j]));sort(temp.begin(),temp.end());//排序ostringstream oss;oss<<i<<","<<j;uniqueKVs[oss.str()]=temp;}}for(const auto & elem :uniqueKVs){//查找符合条件的std::string k=elem.first;size_t pos=k.find(",");int i=std::stoi(k.substr(0,pos));int j=std::stoi(k.substr(pos+1,k.size()-pos-1)); vector<int> temp=elem.second;for(int k=0;k<nums.size();k++){if(i!=j && i!=k && j!=k && nums[i]+nums[j]+nums[k]==0){ostringstream oss;oss<<temp[0]<<temp[1]<<temp[2];std::string temposs=oss.str();cout<<oss.str()<<endl;if(uniqueValues.find(temposs)!=uniqueValues.end()){//结果去重//cout<<temposs<<endl;}else{uniqueValues.insert(temposs);res.push_back(temp);}}}}return res;}
};
优化方法2:
class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {vector<vector<int>> res;sort(nums.begin(),nums.end());//排序 方便 去重 和查找for(int i=0;i<nums.size();i++){//优化下,选择二个if(i==0 || nums[i] != nums[i-1]){//去除 越界 和重复的值int k=nums.size()-1;//双指针 左右 逼近 使得并行查找for(int j=i+1;j<nums.size();j++){if(j==i+1 || nums[j]!=nums[j-1]){//去除 越界 和重复的值while(j<k && nums[i]+nums[j]+nums[k]>0){k--;//并行查找合适的 k对应的值}if(j==k){break;// 左边和右边 通过双指针都 查找了,不能再存在符合条件的了}if(nums[i]+nums[j]+nums[k]==0){//获得符合条件的res.push_back({nums[i],nums[j],nums[k]});}}}}}return res;}
};