Leetcode 15. 3Sum
Given an array S of n integers, are there elements a, b, c in S 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.
For example, given array S = [-1, 0, 1, 2, -1, -4], A solution set is: [ [-1, 0, 1], [-1, -1, 2] ]
解法一:
这一题如果用解决combination的DFS思路,会导致出现很多重复解。比如见下图的例子,假设存在一个解是[-5,-2,7], 由于-2在list中出现了两次,所以这个解至少会出现两次。
1.可以先对nums进行排序。
2. 对于k in range(n), 我们考察[k+1,n]这个区间。由于要求三个数的和为零。所以nums[i]+nums[j]的target就是 -nums[k]。
2.1 如果 nums[i]+nums[j] == target, i 右移一格,j 左移一格。为了不出现重复解,下图的情况 i 要移动到不是-2为止。
2.2 如果 nums[i]+nums[j] < target, i 右移一格
2.3 如果 nums[i]+nums[j] > target, j 左移一格
L12是为了第一个数不出现重复的情况,所以如果nums[k] == nums[k+1], 那么k+1这一步就直接跳过。 另外和two sum不同的是,这里由于事先做了排序,所以并不需要建立一个Hash table。
1 class Solution(object): 2 def threeSum(self, nums): 3 """ 4 :type nums: List[int] 5 :rtype: List[List[int]] 6 """ 7 nums.sort() 8 res = [] 9 n = len(nums) 10 for k in range(n): 11 if nums[k] > 0: break 12 if (k>0 and nums[k] == nums[k-1]): continue 13 target = 0 - nums[k] 14 i, j = k+1, n - 1 15 while i < j: 16 if nums[i] + nums[j] == target: 17 res.append([nums[k], nums[i], nums[j]]) 18 while i<j and nums[i] == nums[i+1]: 19 i += 1 20 while i<j and nums[j] == nums[j-1]: 21 j -= 1 22 i += 1; j -= 1 23 elif nums[i] + nums[j] < target: 24 i += 1 25 else: 26 j -= 1 27 return res