题目:
暴力方法:
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;
}
};