Problem solving
subject
thinking
When I first saw this problem, I still had the solution of "sum of two numbers" in my mind. And according to the prompt of the button, it seems that after an element is fixed, the function of "sum of two numbers" can be called to complete.
Then, traverse the entire array, making target=-nums[i], so that the "sum of two numbers" can be called perfectly.
Finally, set is used to de duplicate the result array.
Unfortunately, it's over time.
I decided to use double pointer after referring to netizen's solution. The left and right pointers are i-1 and i+1
Then i=1 to i=size-2
Every time the sum of three numbers is equal to 0, an array is temporarily created, three numbers are inserted into the array, and after sorting (convenient for de duplication), the array is inserted into the result array. Then l++,r –
If the sum of three numbers is less than 0, then l + +; otherwise r –
And then Time out. There are more than one hundred zeros in the last example, none of which have been passed.
So I had to change the thinking of double pointer.
Change from l=i-1,r=i+1 to l=i+1,r=size-1
Then, especially for the last example, when sum of three numbers is sum=0, if the value of the left pointer does not change, it always jumps; so does the right pointer. Thus, in the last example, it avoids the trouble of going over again after calculating a large number of [0,0,0] results.
Generally speaking, the time complexity of the three codes is actually O(n ²). But the key is the run time for the particular samples. Sometimes the special pit made by the buckle Later, I learned that less than 30% of the submission accuracy of this question, most of which was due to the overtime
code
class Solution { public: vector<vector<int>> threeSum(vector<int>& nums) { vector<vector<int>> ans; if(nums.size()==0)return ans;//For one of the '[]' samples sort(nums.begin(),nums.end());//Sorting, easy to traverse for(int i=0;i<nums.size()-1;i++){ if(nums[i]>0)break;//When it is greater than 0, the value of double pointer must be greater than 0, and there must be no problem int l=i+1,r=nums.size()-1;//Double pointer while(l<r){ //Within limits int sum=nums[i]+nums[l]+nums[r]; if(sum==0){ vector<int> tmp; tmp.push_back(nums[i]); tmp.push_back(nums[l]); tmp.push_back(nums[r]); sort(tmp.begin(),tmp.end());//Sorting, convenient for de duplication ans.push_back(tmp); while (l<r && nums[l] == nums[l+1]) l++; // De duplication for the last example while (l<r && nums[r] == nums[r-1]) r--; // duplicate removal r--;l++; } else if(sum>0){ r--; } else { l++; } } } set<vector<int>> st(ans.begin(),ans.end()); ans.assign(st.begin(),st.end());//Convenient set de duplication return ans; } };
Code with two pointers to the left and right (last example timed out)
class Solution { public: vector<vector<int>> threeSum(vector<int>& nums) { vector<vector<int>> ans; if(nums.size()==0)return ans; sort(nums.begin(),nums.end()); for(int i=1;i<nums.size()-1;i++){ int l=i-1,r=i+1;//Double pointer while(l>=0&&r<=nums.size()-1){ //Within limits int sum=nums[i]+nums[l]+nums[r]; if(sum==0){ vector<int> tmp; tmp.push_back(nums[i]); tmp.push_back(nums[l]); tmp.push_back(nums[r]); sort(tmp.begin(),tmp.end()); ans.push_back(tmp); r++;l--; } else if(sum<0){ r++; } else { l--; } } } set<vector<int>> st(ans.begin(),ans.end()); ans.assign(st.begin(),st.end()); return ans; } };
Code calling "sum of two" (failed)
class Solution { public: vector<vector<int>> threeSum(vector<int>& nums) { vector<vector<int>> ans; for(int i=0;i<nums.size();i++){ int t=-nums[i]; vector<int> tmp=twoSum(nums,t,i); if(tmp[0]!=-99){//-99 is to screen out the solution tmp.push_back(nums[i]);//The two elements obtained plus the element are a solution sort(tmp.begin(),tmp.end());//To prepare for a remake ans.push_back(tmp); } } set<vector<int>> st(ans.begin(),ans.end()); ans.assign(st.begin(),st.end()); return ans; } vector<int> twoSum(vector<int>& n, int t,int index) { map<int,int> a; vector<int> b(2,-99); int len=n.size(); for(int i=0;i<len;i++){ if(i==index)continue; if(a.count(t-n[i])>0&&a[t-n[i]]!=i){ //It's not clear if repeating elements are not allowed b[0]=n[i]; b[1]=n[a[t-n[i]]];//a[t-n[i]] means that the subscript a of t-n[i] plays the role of inverse function } a[n[i]]=i; } return b; }//Code of sum of two numbers };