15. 3Sum
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]
]
Code:
class Solution(object):
def threeSum(self, nums):
res = []
nums.sort()
length = len(nums)
for i in range(length-2): #[8]
if nums[i]>0: break #[7]
if i>0 and nums[i]==nums[i-1]: continue #[1]
l, r = i+1, length-1 #[2]
while l<r:
total = nums[i]+nums[l]+nums[r]
if total<0: #[3]
l+=1
elif total>0: #[4]
r-=1
else: #[5]
res.append([nums[i], nums[l], nums[r]])
while l<r and nums[l]==nums[l+1]: #[6]
l+=1
while l<r and nums[r]==nums[r-1]: #[6]
r-=1
l+=1
r-=1
return res
https://leetcode.com/problems/3sum/discuss/232712/Best-Python-Solution-(Explained)
Thanks to christopherwu0529 for his/her expliantion
this is the answer from caikehe and all the comments below
the main idea is to iterate every number in nums.
we use the number as a target to find two other numbers which make total zero.
for those two other numbers, we move pointers, l and r, to try them.
l start from left to right
r start from right to left
first, we sort the array, so we can easily move i around and know how to adjust l and r.
if the number is the same as the number before, we have used it as target already, continue. [1]
we always start the left pointer from i+1 because the combination has already tried. [2]
now we calculate the total
if the total is less than zero, we need it to be larger, so we move the left pointer. [3]
if the total is greater than zero, we need it to be smaller, so we move the right pointer. [4]
if the total is zero, bingo! [5]
we need to move the left and right pointers to the next different numbers, so we do not get repeating result. [6]
we do not need to consider i after nums[i]>0, since sum of positive will be always greater than zero. [7]
we do not need to try the last two, since there are no rooms for l and r pointers.
You can think of it as The last two have been tried by all others. [8]