🚀总结
首先,需要对数组排序,以便最大限度利用数组元素之间的相对大小关系。
遍历排序后的数组中的每一个元素 nums[i]
:
- 如果
nums[i] > 0
,则在其右侧不再可能出现两数之和为负数; - 如果
nums[i] == nums[i - 1]
,则跳过,避免重复的解; - 对于一般情况,通过双指针在
nums[i]
的右侧找到nums[l] + nums[r] + nums[i] == 0
- 如果
nums[l] + nums[r] + nums[i] == 0
,添加至结果列表,并跳过重复元素; - 如果
nums[l] + nums[r] + nums[i] < 0
,左指针右移,使得三数之和变得更大; - 如果
nums[l] + nums[r] + nums[i] > 0
,右指针左移,使得三数之和变得更小;
- 如果
📇题目
🛠️代码
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
res = [] # res 存储最终结果
nums.sort() # 对数组进行排序
n = len(nums)
for i in range(n): # 遍历数组中每一个数字
if nums[i] > 0: # 如果第 i 个数字大于 0
return res # 后面不可能出现三数之和等于 0,直接返回最终结果
if i > 0 and nums[i] == nums[i - 1]: # 如果第 i 个数字等于前面一个数字
continue # 跳过,避免重复的解
# 对于一般情况
l = i + 1 # 左指针从第 i 个数字后面一位开始
r = n - 1 # 右指针从数组最后一位开始
while l < r: # 遍历左右指针
if nums[i] + nums[l] + nums[r] == 0: # 如果 i l r 对应位置数字之和为 0
res.append([nums[i], nums[l], nums[r]]) # 添加至最终结果中
while l < r and nums[l + 1] == nums[l]: # 如果 l + 1 位置的数字等于 l 位置的数字
l += 1 # 左指针右移一位,使得 l 最终对应的是最后一个不重复的数字
while l < r and nums[r - 1] == nums[r]: # 如果 r - 1 位置的数字等于 r 位置的数字
r -= 1 # 右指针左移一位,使得 r 最终对应的是最后一个不重复的数字
l += 1 # l 和 r 同时向中间移动,直到不满足 nums[i] + nums[l] + nums[r] == 0
r -= 1
elif nums[i] + nums[l] + nums[r] > 0: # 如果 i l r 对应位置数字之和大于 0
r -= 1 # 右指针左移一位,使得三数之和变得更小
elif nums[i] + nums[l] + nums[r] < 0: # 如果 i l r 对应位置数字之和小于 0
l += 1 # 左指针右移一位,使得三数之和变得更大
return res # 返回最终结果