1. LeetCode Hot 100 刷题的价值与策略刷LeetCode Hot 100是算法能力提升的高效路径。这100道题目经过大量用户真实提交数据筛选覆盖了面试中最常考察的算法模式和数据结构。Day6的题目15/100三数之和是其中的经典题型它考察的是对双指针技巧的灵活运用以及对边界条件的处理能力。在实际面试中类似三数之和的问题经常出现在大厂的初面环节。根据我的面试官经验约60%的候选人能写出基础解法但只有不到20%能正确处理所有边界情况并给出优化方案。这道题的价值在于它训练了将复杂问题分解为已知模式两数之和的能力这正是算法思维的核心。2. 题目15三数之和的暴力解法分析2.1 问题描述与初步理解给定包含n个整数的数组nums判断是否存在三个元素a、b、c使得a b c 0需要找出所有不重复的三元组。示例输入nums [-1,0,1,2,-1,-4] 输出[[-1,-1,2],[-1,0,1]]2.2 三重循环的暴力解法最直观的解法是三层嵌套循环def threeSum(nums): res [] n len(nums) for i in range(n): for j in range(i1, n): for k in range(j1, n): if nums[i] nums[j] nums[k] 0: triplet sorted([nums[i], nums[j], nums[k]]) if triplet not in res: res.append(triplet) return res这种解法时间复杂度为O(n³)在LeetCode上会超时。但理解这个基础版本很重要它是我们优化思路的起点。注意即使在这种低效解法中处理重复三元组的方式先排序再检查已经暗示了后续优化的方向。3. 排序双指针的优化方案3.1 算法思路拆解排序预处理首先将数组排序O(nlogn)这使得我们可以利用有序性跳过重复元素和指导指针移动固定一个数外层循环遍历数组固定当前元素作为第一个数nums[i]双指针找目标在内层使用左右指针初始位于i1和末尾根据三数之和与0的关系移动指针和0右指针左移和0左指针右移和0记录结果并跳过重复元素3.2 完整实现代码def threeSum(nums): nums.sort() res [] n len(nums) for i in range(n-2): if i 0 and nums[i] nums[i-1]: continue # 跳过重复元素 left, right i1, n-1 while left right: total nums[i] nums[left] nums[right] if total 0: left 1 elif total 0: right - 1 else: res.append([nums[i], nums[left], nums[right]]) # 跳过左侧重复 while left right and nums[left] nums[left1]: left 1 # 跳过右侧重复 while left right and nums[right] nums[right-1]: right - 1 left 1 right - 1 return res3.3 时间复杂度分析排序O(nlogn)外层循环O(n)内层双指针O(n) 总体复杂度为O(n²)相比暴力解法是质的飞跃4. 关键细节与边界处理4.1 去重机制的实现去重是这道题最容易出错的部分需要在三个层面处理外层循环去重当nums[i] nums[i-1]时跳过避免固定相同的第一个数找到解后的去重在记录有效解后需要跳过所有连续的相同nums[left]和nums[right]提前终止条件当nums[i] 0时可以提前结束因为排序后后面的数都更大不可能三数和为04.2 指针移动的边界条件while left right and nums[left] nums[left1]: left 1这段代码必须保证left right否则在最后两个元素时会越界。这是新手常见的错误点。4.3 输入特殊情况的处理数组长度小于3直接返回空列表全零数组需要正确处理多个[0,0,0]的情况所有元素相同但不满足条件如[1,1,1,...]5. 算法变种与扩展思考5.1 最接近的三数之和LeetCode 16题将条件改为找和最接近target的三元组核心逻辑相似但需要维护最小差值if abs(total - target) abs(closest - target): closest total5.2 四数之和LeetCode 18题在三数之和基础上再加一层循环时间复杂度升到O(n³)但核心思想一致排序数组两层固定前两个数内层使用双指针找后两个数5.3 实际工程中的应用场景这种多指针技术常见于数据库的多条件查询优化游戏开发中的碰撞检测金融分析中的多因子组合筛选6. 刷题经验与调试技巧6.1 测试用例设计建议自己测试时应考虑这些情况[0,0,0,0] # 多个零 [-2,0,1,1,2] # 多个有效解 [1,2,-2,-1] # 无解情况 [] # 空输入 [0,0] # 元素不足6.2 调试打印技巧在双指针移动时添加调试输出print(fi{i}, left{left}, right{right}, sum{nums[i]nums[left]nums[right]})这能清晰看到指针移动轨迹和判断逻辑是否正确。6.3 性能优化实测在我的MacBook Pro上测试n1000暴力解法约8秒双指针解法仅0.02秒n3000暴力解法超时(60s)双指针解法0.15秒7. 常见错误模式分析7.1 去重逻辑错误错误示例# 错误只比较相邻元素 if nums[i] nums[i1]: continue这会导致漏解如[-1,-1,2]会被错误跳过。7.2 指针移动条件错误常见错误是在找到解后只移动一个指针# 错误会导致死循环 if total 0: res.append(...) left 1 # 忘记移动right7.3 边界条件遗漏未处理输入长度不足3的情况# 错误当len(nums)2时会越界 for i in range(len(nums)-2): ...8. 算法思维的进阶训练理解这道题后可以尝试以下练习巩固手动模拟算法在示例输入下的执行过程尝试不排序的解法虽然效率低但锻炼思维改写为返回下标而非元素值的版本思考如果允许重复使用元素该如何修改我在实际面试中遇到过这道题的多个变种比如要求返回所有可能的三元组乘积最大的那个核心算法不变只需额外维护最大乘积值。这种举一反三的能力正是刷题的要义。