【LeetCode刷题】三数之和
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4] 输出:[[-1,-1,2],[-1,0,1]] 解释: nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。 nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。 nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。 不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。 注意,输出的顺序和三元组的顺序并不重要。
示例 2:
输入:nums = [0,1,1] 输出:[] 解释:唯一可能的三元组和不为 0 。
示例 3:
输入:nums = [0,0,0] 输出:[[0,0,0]] 解释:唯一可能的三元组和为 0 。
提示:
3 <= nums.length <= 3000-105 <= nums[i] <=
解题思路:
- 排序数组:先对数组进行排序,以便后续利用双指针缩小范围,同时方便去重。
- 固定第一个数:遍历数组,将当前元素作为三元组的第一个数
nums[i]。若nums[i] > 0,则后续元素均大于 0,和不可能为 0,直接终止循环。 - 双指针找另外两个数:对于每个
nums[i],使用左指针l = i+1和右指针r = len(nums)-1,计算三者的和:- 若和为 0,记录该三元组,并移动指针跳过重复元素(避免重复三元组)。
- 若和小于 0,左指针右移(增大和)。
- 若和大于 0,右指针左移(减小和)。
- 去重处理:在遍历第一个数和移动双指针时,均需跳过重复元素,确保结果中无重复三元组。
Python代码:
from typing import Listclass Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:n = len(nums)if n < 3:return []nums.sort()res = []for i in range(n):# 若当前数大于0,后续数更大,和不可能为0,直接breakif nums[i] > 0:break# 去重:避免第一个数重复导致的重复三元组if i > 0 and nums[i] == nums[i-1]:continuel, r = i + 1, n - 1while l < r:total = nums[i] + nums[l] + nums[r]if total == 0:res.append([nums[i], nums[l], nums[r]])# 去重:避免左右指针重复元素导致的重复三元组while l < r and nums[l] == nums[l + 1]:l += 1while l < r and nums[r] == nums[r - 1]:r -= 1l += 1r -= 1elif total < 0:l += 1else:r -= 1return resif __name__ == "__main__":# 处理输入(格式如:nums = [-1,0,1,2,-1,-4])input_str = input().strip()# 提取数组部分并转换为整数列表nums = eval(input_str.split("=")[1].strip())# 实例化类并调用方法solution = Solution()result = solution.threeSum(nums)# 输出结果print(result)
LeetCode提交代码:
class Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:from typing import Listn = len(nums)if n < 3:return []nums.sort()res = []for i in range(n):# 若当前数大于0,后续数更大,和不可能为0,直接breakif nums[i] > 0:break# 去重:避免第一个数重复导致的重复三元组if i > 0 and nums[i] == nums[i-1]:continuel, r = i + 1, n - 1while l < r:total = nums[i] + nums[l] + nums[r]if total == 0:res.append([nums[i], nums[l], nums[r]])# 去重:避免左右指针重复元素导致的重复三元组while l < r and nums[l] == nums[l + 1]:l += 1while l < r and nums[r] == nums[r - 1]:r -= 1l += 1r -= 1elif total < 0:l += 1else:r -= 1return res

总结
题目要求在整数数组nums中找到所有不重复的三元组[nums[i], nums[j], nums[k]],满足i≠j≠k且三数之和为0。采用排序+双指针法:先排序数组,遍历固定第一个数,用双指针在剩余范围搜索另外两个数。通过跳过重复元素避免重复解。时间复杂度为O(n²),空间复杂度为O(1)。示例:输入[-1,0,1,2,-1,-4],输出[[-1,-1,2],[-1,0,1]]。关键步骤包括排序、双指针移动及去重处理。
