演算法34--3Sum,3Sum Closest,4Sum
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]
]
給定一個數組,選出三元組使其和為0 三元組不能重複。
將陣列排序,固定第一個指標k來進行遍歷,然後利用雙指標i,j分別從陣列k+1--len-1向中點尋找,
當sum=nums[k]+nums[i]+nums[j]==0 直接輸出
當sum<0,說明過小,此時移動i指標即可,i++,否則移動j即可,j--
def threeSum(nums=[-2,0,0,2,2]): nums.sort() #print(nums) rr = [] for k in range(len(nums)-1): i = k+1 j = len(nums)-1 while i<j: #print(k, i, j) sum = nums[k] + nums[i] + nums[j] if sum==0: rr.append([nums[k], nums[i], nums[j]]) i += 1 j -= 1 elif sum<0: i += 1 else: j -= 1 return rr
程式碼如上所示,輸出結果並沒有去除重複結果,現在考慮一下重複值的產生情況:
給定陣列以及三個指標k,i,j 0---k---i----j---len-1
當nums[k-1]==nums[k]相同時,可以直接k++,進行下一次迴圈,否則可能會產生重複 例如 -1 -1 0 1 1當k=0與k=1時會產生重複;
當k遍歷依次遞加沒有重複,考慮i位置的重複,當某一元組(k,i,j)符合條件時,此時如果nums[i+1]==nums[j],此時如果執行i++,j--,可能會產生重複,處理方式是當找到符合條件的三元組時,此時應該移動i,j的指標直到nums[i·]不等於nums[i],以及nums[j`]不等於nums[j]
def threeSum(nums=[-2,0,0,2,2]):
nums.sort()
#print(nums)
rr = []
for k in range(len(nums)-1):
if k>=1 and nums[k-1]==nums[k]:
continue
i = k+1
j = len(nums)-1
while i<j:
#print(k, i, j)
sum = nums[k] + nums[i] + nums[j]
if sum==0:
rr.append([nums[k], nums[i], nums[j]])
while i<j and nums[i+1]==nums[i]:
i += 1
while i<j and nums[j-1]==nums[i]:
j -= 1
i += 1
j -= 1
elif sum<0:
i += 1
else:
j -= 1
return rr
Given an array nums
of n integers and an integer target
, find three integers in nums
such that the sum is closest to target
. Return the sum of the three integers. You may assume that each input would have exactly one solution.
Example:
Given array nums = [-1, 2, 1, -4], and target = 1.
The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
給定陣列,找到一個三元組,使其和最接近target.
將陣列排序,維持一個全域性最小差值,利用陣列有序以及三指標來調整位置,尋找可能的最小差值
def threeSumClosest(nums=[-4,-1,1,2], target=1):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
nums.sort()
minv = nums[0]+nums[1]+nums[-1]
mind = abs(nums[0]+nums[1]+nums[-1]-target)
#print(minv, mind)
for k in range(len(nums)):
i = k+1
j = len(nums)-1
while i<j:
diff = nums[k] + nums[i] + nums[j] - target
#print(k,i,j,diff,mind)
if diff==0:
return target
else:
if abs(diff)<=mind:
minv = nums[k] + nums[i] + nums[j]
mind = abs(diff)
#print(minv, mind)
if diff<0:
i += 1
else:
j -= 1
return minv
Given an array nums
of n integers and an integer target
, are there elements a, b, c, and d in nums
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.
Example:
Given array nums = [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]
]
給定一個數組,尋找非重複四元組使其和等於target.
類似於三元組和問題,如果暴力求解時間複雜度為N4.
首先將陣列排序,陣列變為有序之後。利用兩個指標來遍歷前兩個元素,後面再利用雙指標從頭尾向中間遞進,依次尋找符合條件的組合解,將時間複雜度降為N2logN
class Solution:
def fourSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[List[int]]
"""
nums.sort()
rr = []
for k in range(len(nums)):
if k>0 and nums[k]==nums[k-1]:
continue
for m in range(k+1, len(nums)):
if m>k+1 and nums[m]==nums[m-1]:
continue
i=m+1
j=len(nums)-1
while i<j:
sum=nums[k]+nums[m]+nums[i]+nums[j]
if sum==target:
rr.append([nums[k],nums[m],nums[i],nums[j]])
while i<j and nums[i]==nums[i+1]:
i += 1
while i<j and nums[j]==nums[j-1]:
j -= 1
i += 1
j -= 1
elif sum<target:
i += 1
else:
j -= 1
return rr
去重要考慮四個指標的去重,k,m分別從頭向尾遍歷,因此去重要考慮每一個元素與前一個元素是否相同,如果相同則直接跳過進行下一個元素遍歷;i,j分別從頭尾向中間遍歷遞進,當找到符合條件的元組時,i,j應該繼續向中間逼近,直到取到新的不同於上一個值為止,繼續進行求和與target的大小判斷,即可去重。