# [leetcode]4Sum @ Python

需要用到哈希表的思路，这样可以空间换时间，以增加空间复杂度的代价来降低时间复杂度。首先建立一个字典dict，字典的key值为数组中每两个元素的和，每个key对应的value为这两个元素的下标组成的元组，元组不一定是唯一的。如对于num=[1,2,3,2]来说，dict={3:[(0,1),(0,3)], 4:[(0,2),(1,3)], 5:[(1,2),(2,3)]}。这样就可以检查target-key这个值在不在dict的key值中，如果target-key在dict中并且下标符合要求，那么就找到了这样的一组解。由于需要去重，这里选用set()类型的数据结构，即无序无重复元素集。最后将每个找出来的解(set()类型)转换成list类型输出即可。

class Solution:
# @return a list of lists of length 4, [[val1,val2,val3,val4]]
def fourSum(self, num, target):
numLen, res, dict = len(num), set(), {}
if numLen < 4: return []
num.sort()
for p in range(numLen):
for q in range(p+1, numLen):
if num[p]+num[q] not in dict:
dict[num[p]+num[q]] = [(p,q)]
else:
dict[num[p]+num[q]].append((p,q))
for i in range(numLen):
for j in range(i+1, numLen-2):
T = target-num[i]-num[j]
if T in dict:
for k in dict[T]:
if k[0] > j: res.add((num[i],num[j],num[k[0]],num[k[1]]))
return [list(i) for i in res]

class Solution:
# @return a list of lists of length 4, [[val1,val2,val3,val4]]
def fourSum(self, num, target):
num.sort(); res=[]
for i in range(len(num)):
if i>0 and num[i]==num[i-1]: continue
for j in range(i+1,len(num)):
if j>i+1 and num[j]==num[j-1]: continue
l=j+1; r=len(num)-1
while l<r:
sum=num[i]+num[j]+num[l]+num[r]
if sum>target:
r-=1
elif sum<target:
l+=1
elif l>j+1 and num[l]==num[l-1]:
l+=1
elif r<len(num)-1 and num[r]==num[r+1]:
r-=1
else:
res.append([num[i],num[j],num[l],num[r]])
l+=1; r-=1
return res

class Solution:
# @return a list of lists of length 4, [[val1,val2,val3,val4]]
def fourSum(self, num, target):
num.sort(); res=[]
for i in range(len(num)-3):
if i==0 or num[i]>num[i-1]:
for j in range(i+1,len(num)-2):
if j==i+1 or num[j]>num[j-1]:
left=j+1; right=len(num)-1
while left<right:
if num[i]+num[j]+num[left]+num[right]==target:
res.append([num[i],num[j],num[left],num[right]])
left+=1; right-=1
while left<right and num[left]==num[left-1]: left+=1
while left<right and num[right]==num[right+1]: right-=1
elif num[i]+num[j]+num[left]+num[right]>target:
while left<right:
right-=1
if num[right]<num[right+1]: break
else:
while left<right:
left+=1
if num[left]>num[left-1]: break
return res

posted @ 2014-04-29 15:46  南郭子綦  阅读(6549)  评论(2编辑  收藏  举报