首页 > 代码库 > Leetcode 15. 3Sum

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

 

Leetcode 15. 3Sum