18. 四数之和
原始题目链接:https://leetcode-cn.com/problems/4sum/
给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。
注意:答案中不可以包含重复的四元组。
解题思路:
和三数之和的思路一样,只是在三数之和的基础上再套一层循环,同样通过去重操作加快遍历,另一个变化是,new_target = target - nums[i] - nums[j],具体实现看代码及注释。
代码实现:
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
n = len(nums)
if not nums or n < 4:
return []
res = []
i = 0
nums.sort()
# nums[i] 小于倒数第3个位置的数
while i < n - 3:
# 说明此时的i已经不满足了,因为nums已排序,后面也不满足,直接跳出循环
if nums[i] + 3 * nums[i + 1] > target:
break
# 说明此时的i过小,需要看i后面的数即自增i继续循环遍历,同时去重和此时相同nums[i]的值
if nums[i] + 3 * nums[-1] < target:
# 去重
while i < n - 4 and nums[i] == nums[i + 1]:
i += 1
# 自增i
i += 1
continue
# 下一个数j,和i一样的操作
j = i + 1
# nums[j] 小于倒数第2个位置的数
while j < n - 2:
if nums[i] + nums[j] + 2 * nums[j + 1] > target:
break
if nums[i] + nums[j] + 2 * nums[-1] < target:
# 去重
while j < n - 3 and nums[j] == nums[j + 1]:
j += 1
# 自增
j += 1
continue
k = j + 1
s = n - 1
new_target = target - nums[i] - nums[j]
while k < s:
if nums[k] + nums[s] > new_target:
s -= 1
elif nums[k] + nums[s] < new_target:
k += 1
else:
res.append([nums[i], nums[j], nums[k], nums[s]])
k += 1
s -= 1
# 去重
while k < s and nums[k] == nums[k - 1]:
k += 1
while k < s and nums[s] == nums[s + 1]:
s -= 1
while j < n - 3 and nums[j] == nums[j + 1]:
j += 1
j += 1
while i < n - 4 and nums[i] == nums[i + 1]:
i += 1
i += 1
return res
参考文献:
https://leetcode-cn.com/problems/4sum/solution/shuang-zhi-zhen-gao-su-jie-fa-by-ml-zimingmeng/