Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note:
The solution set must not contain duplicate triplets.
Example:
1 2 3 4 5 6 7
Given array nums = [-1, 0, 1, 2, -1, -4],
A solution set is: [ [-1, 0, 1], [-1, -1, 2] ]
Solution:
Sort the array
Pick indices from 0…n-2. To n-2 is because we need to find 3 item sequence. If we sort the array, need to at least save one spot for right element.
Bypass duplicate element
Use two pointers, one goes from i+1 toward right, the other one goes from n toward left
If the sum of two pointers can not make the sequence zero, move the point. To clarify, we can only move one pointer to make the result close to zero.
classSolution: defthreeSum(self, nums: List[int]) -> List[List[int]]: res = [] nums.sort() for i in range(len(nums)-2): if i > 0and nums[i] == nums[i-1]: continue l, r = i+1, len(nums)-1 while l < r: s = nums[i] + nums[l] + nums[r] if s < 0: l +=1 elif s > 0: r -= 1 else: res.append((nums[i], nums[l], nums[r])) while l < r and nums[l] == nums[l+1]: l += 1 while l < r and nums[r] == nums[r-1]: r -= 1 l += 1; r -= 1 return res
classSolution { public: vector<vector<int>> threeSum(vector<int>& nums) { vector<vector<int>> res; if(nums.size() <= 2) return res; //edge case check sort(nums.begin(), nums.end()); for(int i = 0; i < nums.size()-2; ++i){ //-2 is because last possible 3Sum sequence could be last 3 item, //and the center is n-2 if(i>0 && nums[i] == nums[i-1]) //pass duplicate elements continue; int j=i+1, k=nums.size()-1; int target = 0-nums[i]; //because the other two elements would make sequence zero while(j< k){ if(nums[j]+ nums[k] == target){ res.push_back(vector<int>{nums[i], nums[j], nums[k]}); j++; k--; while(j<k && nums[j]==nums[j-1]) j++;//skip same element while(j<k && nums[k]==nums[k+1]) k--;//skip same element } elseif(nums[j]+ nums[k]>target){ k--; } else{ j++; } } } return res;