3Sum
2Sum
先将数组排序,然后用两个指针分别从头和尾扫描。
class Solution(object):
def twoSum(self, nums, target):
if len(nums) < 2:
return []
nums.sort()
first = 0
last = len(nums) - 1
while first < last:
if nums[first] + nums[last] == target:
return [nums[first],nums[last]]
elif nums[first] + nums[last] < target:
first += 1
else:
last -= 1
return []
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.
中文:一个数组,找出其中的三个数,让其相加为0.返回的结果不能包含重复组合
举例:
For example, given array S = [-1, 0, 1, 2, -1, -4],
A solution set is:
[
[-1, 0, 1],
[-1, -1, 2]
]
方法
3Sum可以转化为2Sum问题,固定一个数num,然后利用2Sum的方法寻找和为
target - num
的另外的两个数。结果去重。
因为数组有序,对于 nums[i],寻找另外两个数时,只要从 nums[i+1] 开始找就可以了;
原因:
nums[0] ~ nums[i - 1]
已经查找过是否会与nums[i]组成一组数,避免重复查找,也为了提高查找效率,从nums[i+1]
查找即可。如果nums[i] 等于nums[i - 1],直接跳过;
nums[i - 1] + x + y == target,nums[i] == nums[i - 1],重复结果,没意义啊…
nums[i - 1]找全了所有能与nums[i - 1]组合的数,nums[i] == nums[i - 1],所以nums[i]再找也是重复结果。
code
#!/usr/bin/python
# -*- coding: utf-8 -*-
class Solution(object):
def quicksort(self,a,start,end):#快排排序
if not a or start >= end:
return a
temp = a[start]
left,right = start,end
while left < right:
while a[right] >= temp and left < right:
right -= 1
a[left] = a[right]
while a[left] <= temp and left < right:
left += 1
a[right] = a[left]
a[left] = temp
self.quicksort(a,start,left - 1)
self.quicksort(a,left + 1,end)
return a
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
length = len(nums)
if length < 3: #小于三个的话肯定不行
return []
nums = self.quicksort(nums,0,length - 1)#排序
result = []
pos = 0 #固定一个数
while pos < length - 2: #查找到倒数第三个就行了,保证剩余三个数
#查找和为target - nums[pos]的另外的另个数
#去掉重复结果,num[pos - 1]找全了所有能与num[pos - 1]组合的数,nums[pos]再找也是重复结果。
while pos > 0 and nums[pos] == nums[pos-1] and pos < length - 2:
pos += 1
target = - nums[pos]
first = pos + 1 #从pos之后的元素查找就行了
last = length - 1
while first < last:
if nums[first] + nums[last] == target:
result.append([nums[pos],nums[first],nums[last]])
#nums[first] + nums[last] + nums[pos] = 0,
#nums[first + 1] + nums[last] + nums[pos] = 0,nums[first] == nums[first + 1],重复结果
while nums[first] == nums[first + 1] and first < length -2:
first += 1
#同上
while nums[last] == nums[last - 1] and last > pos + 1:
last -= 1
#一个数变大,一个数减小,相加才可能得到target
last -= 1
first += 1
elif nums[first] + nums[last] > target:#比target大,减小两数之和
last -= 1
else:#比target小,增大两数之和
first += 1
pos += 1
return result
if __name__ == "__main__":
s = Solution()
print s.threeSum([-2,0,0,2,2])
print s.threeSum( [-1,0,1,2,-1,-4])