题目:leetcode18 4Sum
链接:https://leetcode.com/problems/4sum/#/description
原题:
Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
Note: The solution set must not contain duplicate quadruplets.
For example, given array S = [1, 0, -1, 0, -2, 2], and target = 0. A solution set is: [ [-1, 0, 0, 1], [-2, -1, 1, 2], [-2, 0, 0, 2] ]
解题思路:
这题4Sum与上周完成的3Sum是同一类型题目,不过是将题目扩大难度,其实就是泛化了这类题目。题目意思是从给出的数列里找出4个数字能够相加得到target,但答案不能重复。
解题思路不过是将上周题目的代码再加一个循环而已,这里就不具体介绍了。接下来介绍一下如何做N-Sum的问题。
2-Sum问题是最简单的N-Sum问题,他是解决所有N-Sum问题的核心,方法是先将数列排序,然后从数列两边开始遍历,假设L是数列最左边的数字,R是数列最右边的数字,L+R>target的话则将R往前挪一个,反之小于的话则将L往右挪一个,等于的话就作为答案输出。
3-Sum问题是在2-Sum问题基础上套一层循环,按顺序遍历数列中的每一个数字假设他是答案的成员之一,然后再用2-Sum的方法去解决;
4-Sum问题是在3-Sum之上再多一个维度,那就套两个循环,假设遍历到的那两个数字是答案的组成成员,然后用2-Sum求解;
那N-Sum难道是套N层循环吗,答案肯定不是,因为他们之间有一个递归的规律,我们可以用函数递归的方式去实现代码。
代码:由于我在做这题的时候还没想到用递归实现,只是用最快的方法实现两层循环解决问题
class Solution(object):
def fourSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[List[int]]
"""
ret_list = []
nums.sort()
for i in range(0, len(nums)):
if i > 0 and nums[i] == nums[i-1]:
continue
n_1 = nums[i]
for j in range(i+1, len(nums)):
if j > i+1 and nums[j] == nums[j-1]:
continue
n_2 = nums[j]
n_left = j+1
n_right = len(nums)-1
while n_left < n_right:
if n_1+n_2+nums[n_left]+nums[n_right] > target:
n_right -= 1
elif n_1+n_2+nums[n_left]+nums[n_right] < target:
n_left += 1
else:
ret_list.append([n_1, n_2, nums[n_left], nums[n_right]])
while n_left < n_right and nums[n_left] == nums[n_left+1]:
n_left += 1
while n_left < n_right and nums[n_right] == nums[n_right-1]:
n_right -= 1
n_left += 1
n_right -= 1
return ret_list
if __name__ == '__main__':
sol = Solution()
print sol.fourSum([1,0,-1,0,-2,2], 0)