leetcode 18 四數之和

2021-10-06 08:17:14 字數 3948 閱讀 2564

給定乙個包含 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]

]參考2數之和、3數之和的解題思路,採用多指標方法遍歷整個陣列。問題轉化,通過固定指標將問題模型轉化為兩數之和,然後利用兩數之和的解法進行求解。

因為要求4數之和,所以要先固定2個指標。

(0)陣列排序

(1)固定第乙個指標p

if nums[p] + 3 * nums[p+1] > target:

break

如果當前指標指向值加上3倍下一位陣列的值大於target,終止搜尋。

這是因為陣列是排好序的,如果滿足了上述條件,是找不到四個數滿足相加等於target。

if nums[p] + 3* nums[-1] < target:

while p < n-4 and nums[p] == nums[p+1]:

p += 1

p += 1

continue

如果當前指標指向的值加上3倍的陣列最大元素仍然小於target,說明p指向的值太小,要向右移動,

同時,while迴圈跳過相同的元素,p < n-4 即 p < n - 3 -1 要找到4個數,所以p的最大位置就是

n-3,再減去1是要保證nums[p+1]有值。while迴圈跳過時nums[p] != nums[p+1],固定p+1

位置,尋找剩下的資料。

外迴圈也是while結構,所以這裡的continue還是從p+1位置開始的,如果是for迴圈,則p的自加操作

要省去。

(2)固定第二個指標k,k從p的下乙個位置開始

# k 從p的下乙個位置開始

k = p + 1

# 固定k之後,還有2個資料要查詢,所以k的最大位置是n-2

while k < n-2:

# 與p做相同的判斷以及去重操作

if nums[p] + nums[k] + 2 * nums[k+1] > target:

break

if nums[p] + nums[k] + 2 * nums[-1] < target:

while k < n - 3 and nums[k] == nums[k+1]:

k += 1

k += 1

continue

(3)固定p、k指標後,問題模型就變成了查詢兩數之和

i = k + 1 # 左指標

j = n - 1 # 右指標

while i < j:

if nums[i] + nums[j] > new_target:

j -= 1

elif nums[i] + nums[j] < new_target:

i += 1

else:

i += 1

j -= 1

while i < j and nums[i] == nums[i-1]: i += 1 # 去重

while i < j and nums[j] == nums[j+1]: j-=1 # 去重

(4)完整**

class solution:

def foursum(self, nums: list[int], target: int) -> list[list[int]]:

nums.sort()

n = len(nums)

res =

p = 0

while p < n - 3:

if nums[p] + 3 * nums[p+1] > target:

break

if nums[p] + 3 * nums[-1] < target:

while p < n - 4 and nums[p] == nums[p+1]:

p += 1

p += 1

continue

k = p + 1

while k < n - 2:

if nums[p] + nums[k] + 2 * nums[k+1] > target:

break

if nums[p] + nums[k] + 2 * nums[-1] < target:

while k < n - 3 and nums[k] == nums[k+1]:

k += 1

k += 1

continue

i = k + 1

j = n - 1

new_target = target - nums[p] - nums[k]

while i < j:

if nums[i] + nums[j] > new_target:

j -= 1

elif nums[i] + nums[j] < new_target:

i += 1

else:

i += 1

j -= 1

while i < j and nums[i] == nums[i-1]: i += 1

while i < j and nums[j] == nums[j+1]: j-=1

while k < n - 3 and nums[k] == nums[k+1]:k+=1 # 去重

k += 1

while p < n - 4 and nums[p] == nums[p+1]:p+=1 # 去重

p += 1

return res

依然是參考2數之和、三數之和解法,引入字典。

直接上**

class solution:

def foursum(self, nums: list[int], target: int) -> list[list[int]]:

res =

#hash_map = {}

nums.sort()

res_hash = {}

hash_map =

if len(nums) < 4:

return res

for i,first in enumerate(nums):

if i > 0 and nums[i-1] == first:continue

for j,second in enumerate(nums[i+1:]):

if j > 0 and second == nums[i+1+j-1]:continue

for k,third in enumerate(nums[i+1+j+1:]):

curr = first + second + third

if target - curr in hash_map:

fourth_index = hash_map[target-curr]

if fourth_index == i or fourth_index == i+1+j or fourth_index == i+1+j+1+k:

continue

row = sorted([first,second,third,nums[fourth_index]])

"""key = ''.join([str(x) for x in row])

if key not in res_hash:

res_hash[key] = true

"""if row not in res:

return res

LeetCode 18 四數之和

給定乙個包含 n 個整數的陣列 nums 和乙個目標值 target,判斷 nums 中是否存在四個元素 a,b,c 和 d 使得 a b c d 的值與 target 相等?找出所有滿足條件且不重複的四元組。注意 答案中不可以包含重複的四元組。示例 給定陣列 nums 1,0,1,0,2,2 和 ...

LeetCode 18 四數之和

給定乙個包含 n 個整數的陣列nums和乙個目標值target,判斷nums中是否存在四個元素 a,b,c 和 d 使得 a b c d 的值與target相等?找出所有滿足條件且不重複的四元組。注意 答案中不可以包含重複的四元組。示例 給定陣列 nums 1,0,1,0,2,2 和 target ...

leetcode18 四數之和

def foursum nums,target numlen,res,d len nums set if numlen 4 return nums.sort 二層迴圈遍歷任意兩個元素對和存放到字典d裡並把序號存起來 for p in range numlen for q in range p 1,n...