LeetCode题解:18.四数之和【Python题解超详细】,三数之和 vs. 四数之和
题目描述
给你一个由 n
个整数组成的数组 nums
,和一个目标值 target
。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]]
(若两个四元组元素一一对应,则认为两个四元组重复):
0 <= a, b, c, d < n
a
、b
、c
和d
互不相同nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。
示例 1:
输入:nums = [1,0,-1,0,-2,2], target = 0 输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
示例 2:
输入:nums = [2,2,2,2,2], target = 8 输出:[[2,2,2,2]]
解答
class Solution(object):
def fourSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[List[int]]
"""
# 最终结果列表
result = []
# 如果输入列表为空或长度小于4,直接返回空列表
if not nums or len(nums) < 4:
return result
# 对数组进行排序,以便使用双指针法
nums.sort()
n = len(nums)
# 第一层循环:固定第一个数
for i in range(n - 3):
# 跳过重复元素,避免结果重复
if i > 0 and nums[i] == nums[i - 1]:
continue
# 剪枝:当前最小的四个数和已经大于目标值,后续无需处理
if nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target:
break
# 剪枝:当前最大的四个数和还小于目标值,直接跳过当前循环
if nums[i] + nums[n - 3] + nums[n - 2] + nums[n - 1] < target:
continue
# 第二层循环:固定第二个数
for j in range(i + 1, n - 2):
# 跳过重复元素,避免结果重复
if j > i + 1 and nums[j] == nums[j - 1]:
continue
# 剪枝:当前最小的四个数和已经大于目标值,后续无需处理
if nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target:
break
# 剪枝:当前最大的四个数和还小于目标值,直接跳过当前循环
if nums[i] + nums[j] + nums[n - 2] + nums[n - 1] < target:
continue
# 双指针寻找符合条件的剩余两个数
left, right = j + 1, n - 1
while left < right:
# 当前四数之和
s = nums[i] + nums[j] + nums[left] + nums[right]
# 如果找到目标和
if s == target:
result.append([nums[i], nums[j], nums[left], nums[right]])
# 跳过重复元素
while left < right and nums[left] == nums[left + 1]:
left += 1
left += 1
while left < right and nums[right] == nums[right - 1]:
right -= 1
right -= 1
# 如果当前和小于目标值,移动左指针以增加和
elif s < target:
left += 1
# 如果当前和大于目标值,移动右指针以减小和
else:
right -= 1
# 返回结果
return result
思路,排序+双指针:该代码通过 **排序+双指针** 的思路解决四数之和问题。首先对数组排序,然后通过两层循环固定前两个数,并使用双指针在剩余部分寻找符合条件的另外两个数。通过剪枝优化(跳过不可能的情况)和去重操作(避免重复结果),提升效率并确保结果的唯一性。最终将所有符合条件的四元组返回。代码的时间复杂度为 O(),适合中小规模的输入数据。
四数之和 vs. 三数之和
这道题实际上是LeetCode15题:三数之和的拓展版,与使用 排序+双指针 求解三数之和相同的是两者都使用了 排序 + 双指针 的方法来寻找目标组合,即通过固定部分数字后,利用双指针在剩余数组中寻找满足条件的组合。同时,两者都是通过嵌套循环和双指针来解决问题,三数之和的时间复杂度为 O(),四数之和则要多一层循环,其时间复杂度为 O()。并且,在去重逻辑上,两者都需要跳过重复元素以避免重复结果。此外,两者所采用的剪枝思路也是相同的。
根据上述思路,你能想出计算五数之和的思路,并思考它的时间复杂度吗?
感谢阅读,希望对你有所帮助~