LeetCode 18.四数之和
题目:
给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。
注意:
答案中不可以包含重复的四元组。
示例:
给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。
满足要求的四元组集合为:
[
[-1, 0, 0, 1],
[-2, -1, 1, 2],
[-2, 0, 0, 2]
]
思路:
看到这个题目瞬间想到了上题目中三数之和的双指针移动方法,大就左移,小右移。
- 首先sort排序是必须要的,它会让你遍历出符合条件相同元素的情况。
- 去除重复元素,这里有2种方法,一种是用set函数直接去重最后再取出,第二种是通过count来判断并remove 。
方法一:
import copy
class Solution(object):
def fourSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[List[int]]
"""
nums.sort()
ans=set()
#res = []
for i in range(len(nums)-3):
for j in range(i+1,len(nums)-2):
left=j+1#左指针
right=len(nums)-1#右指针
while(right>left):
temp=nums[i]+nums[j]+nums[left]+nums[right]
if temp==target:
#res.append([nums[i],nums[j],nums[left],nums[right]])
ans.add((nums[i],nums[j],nums[left],nums[right]))
left+=1
right-=1
if temp>target:
right-=1#右指针左移
if temp<target:
left+=1#反之
#取出set中元素赋值到list中。
rec=[]
#方法一
for i in ans:
rec.append(list(i))
return rec
#方法二
#print 'res',res
#list_arr = copy.copy(res)
#for k,v in enumerate(list_arr): #删除重复元素
# while res.count(v) >=2:
# res.remove(v)
#print 'temp_list After = ',res
#return res
时间有点感人:
执行用时 :824 ms, 在所有 Python 提交中击败了28.22%的用户
内存消耗 :12.7 MB, 在所有 Python 提交中击败了14.29%的用户
方法二:
这个方法也很巧妙,通过字典记录所有四数拆成两两之和的位置情况,看code理解逻辑吧。
import collections
class Solution(object):
def fourSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[List[int]]
"""
n,res=len(nums),[]
d=collections.defaultdict(list)
nums.sort()
for i in range(n):
for j in range(i+1,n):
s=nums[i]+nums[j]
if target-s in d:
for a,b in d[target-s]:
if b<i and ([nums[a],nums[b],nums[i],nums[j]]) not in res:
res.append([nums[a],nums[b],nums[i],nums[j]])
d[s].append([i,j])
return res
执行用时 :112 ms, 在所有 Python 提交中击败了73.59%的用户
内存消耗 :18.2 MB, 在所有 Python 提交中击败了14.29%的用户
Knowledge, like candlelight, can illuminate a person and countless people.