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:
Given array nums = [-1, 0, 1, 2, -1, -4], A solution set is: [ [-1, 0, 1], [-1, -1, 2] ]
排序 + 双指针
本题的难点在于如何去除重复解。
算法流程:
特判,对于数组长度 nn,如果数组为 nullnull 或者数组长度小于 33,返回 [][]。
对数组进行排序。
遍历排序后数组:
若 nums[i]>0nums[i]>0:因为已经排序好,所以后面不可能有三个数加和等于 00,直接返回结果。
对于重复元素:跳过,避免出现重复解
令左指针 L=i+1L=i+1,右指针 R=n-1R=n−1,当 L<RL<R 时,执行循环:
当 nums[i]+nums[L]+nums[R]==0nums[i]+nums[L]+nums[R]==0,执行循环,判断左界和右界是否和下一位置重复,去除重复解。并同时将 L,RL,R 移到下一位置,寻找新的解
若和大于 00,说明 nums[R]nums[R] 太大,RR 左移
若和小于 00,说明 nums[L]nums[L] 太小,LL 右移
1 class Solution { 2 public: 3 vector<vector<int>> threeSum(vector<int>& a) { 4 const int n = a.size(); 5 vector<vector<int>> res; 6 if (n < 3) return res; 7 std::sort(a.begin(),a.end()); 8 for(int i = 0; i < n; ++i) { 9 if (i!=0 && a[i]==a[i-1]) continue; 10 int low = i+1; 11 int high = n-1; 12 while(low < high) { 13 if(a[low]+a[high]>-a[i]) { 14 high--; 15 } else if(a[low]+a[high]<-a[i]){ 16 low++; 17 } else { 18 std::vector<int> res_tmp = {a[i],a[low],a[high]}; 19 res.emplace_back(res_tmp); 20 21 while (low < high && a[low]==a[low+1]) { 22 low++; 23 } 24 while (low < high && a[high]==a[high-1]) { 25 high--; 26 } 27 low++; 28 high--; 29 } 30 } 31 } 32 return res; 33 } 34 };
借助 2sum中字典的应用。 时间复杂度 o(n**2)
1 class Solution(object): 2 def threeSum(self, nums): 3 """ 4 :type nums: List[int] 5 :rtype: List[List[int]] 6 """ 7 if len(nums) < 3: 8 return [] 9 nums.sort() 10 res = set() 11 for i, v in enumerate(nums[:-2]): 12 d = {} 13 for x in nums[i+1:]: 14 if x not in d: 15 d[-v-x] = 1 16 else: 17 res.add((v, -v-x, x)) 18 return map(list, res)