LeetCode 3Sum问题:双指针法去重及测试用例调试方法
问题:LeetCode 三数之和去重与调试方法
问题背景
原问题为LeetCode的「三数之和」,我采用排序+双指针的思路,目标时间复杂度O(n²),但代码未通过测试用例,核心问题是会生成重复的三元组,代码如下:
class Solution: def threeSum(self, nums: List[int]) -> List[List[int]]: nums.sort() tripl = [] for i in range(0, len(nums)-2): target = 0 left = i+1 right = len(nums)-1 while(left < right): currentSum = nums[i] + nums[left] + nums[right] if currentSum < target: left += 1 elif currentSum > target: right -= 1 else: tripl.append([nums[i], nums[left], nums[right]]) left += 1 right -= 1 return tripl
如何避免生成重复的三元组?
数组排序后重复元素会相邻,只需在三个关键位置添加去重逻辑:
- 固定第一个元素时去重:若当前
nums[i]与前一个元素nums[i-1]相等,说明已处理过相同的起始元素,直接跳过当前循环(需判断i>0避免越界)。 - 找到有效三元组后左指针去重:找到和为0的组合后,左指针持续右移,直到遇到与当前
nums[left]不同的元素,避免重复添加相同左值的三元组。 - 找到有效三元组后右指针去重:同理,右指针持续左移,直到遇到与当前
nums[right]不同的元素。
修改后的正确代码如下:
class Solution: def threeSum(self, nums: List[int]) -> List[List[int]]: nums.sort() tripl = [] n = len(nums) for i in range(n): # 第一个元素去重,跳过重复的起始值 if i > 0 and nums[i] == nums[i-1]: continue left = i + 1 right = n - 1 target = -nums[i] # 简化目标:nums[left]+nums[right]需等于-nums[i] while left < right: current_sum = nums[left] + nums[right] if current_sum < target: left += 1 elif current_sum > target: right -= 1 else: tripl.append([nums[i], nums[left], nums[right]]) # 左指针去重 while left < right and nums[left] == nums[left+1]: left += 1 # 右指针去重 while left < right and nums[right] == nums[right-1]: right -= 1 # 移动指针到下一组不同元素 left += 1 right -= 1 return tripl
资深开发者如何根据LeetCode测试用例调试?
- 手动构造测试用例:针对重复元素(如
[-1,0,1,2,-1,-4])、全零数组([0,0,0,0])、边界长度(长度<3的数组)等场景,本地运行代码对比预期输出。 - 利用平台错误提示:测试用例失败时,对比平台给出的「输入值」「你的输出」「预期输出」,定位差异来源(比如重复三元组的具体位置)。
- 添加打印日志:在关键步骤打印变量(如当前
i值、left/right指向的元素、新增的三元组),直观观察重复产生的环节。 - 分步验证逻辑:拆分代码模块验证,先确认排序是否正确,再检查第一个元素的去重逻辑,最后验证双指针的移动和去重规则。
- 参考高质量题解:卡壳时对比官方题解或高赞题解的思路,排查自己遗漏的细节(比如去重的时机判断)。
内容的提问来源于stack exchange,提问作者Thonky456
相关产品推荐
相关产品推荐

