15分钟解LeetCode

算法面试不是会不会,而是多快能写对。给你15分钟,一道真实LeetCode题,没有提示、没有调试器、只有白板心态。

本文还原一场解LeetCode的全过程:从读题、破题、写代码到边界检查,完整呈现一个工程师的思维速度与工程落地能力。

一、规则

项目 规则
时间 15分钟倒计时
题目 LeetCode真实中等难度题
环境 纯文本编辑器,无智能提示
目标 写出可运行的、覆盖边界的代码
评分 正确性(60%) + 代码质量(20%) + 完成时间(20%)

二、题目

给你一个整数数组 nums,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j != k,且 nums[i] + nums[j] + nums[k] == 0。返回所有和为0且不重复的三元组。

示例:nums = [-1,0,1,2,-1,-4] → 输出 [[-1,-1,2],[-1,0,1]]

约束:3 <= nums.length <= 3000-10^5 <= nums[i] <= 10^5

难度:中等

核心考察:双指针 + 去重 + 边界条件

三、全程实录

00:00 - 02:00 | 读题 + 破题

扫读关键信息:

数组长度最大3000 → O(n²)可接受,O(n³)不行

有重复元素 → 需要去重

返回三元组,不是下标 → 排序不影响结果

思维路径:

复制代码
三数之和 = 固定一个数 + 两数之和问题

两数之和可以用双指针 O(n) 解决
外层固定一个数,遍历 O(n)
总复杂度 O(n²),可接受

选择方案:排序 + 双指针

复制代码
排序 → 固定i → 双指针l=i+1, r=n-1 → 移动指针寻找和为 -nums[i]

02:00 - 05:00 | 手写代码框架

Go 复制代码
func threeSum(nums []int) [][]int {
    sort.Ints(nums)
    result := [][]int{}
    n := len(nums)
    
    for i := 0; i < n-2; i++ {
        // 去重:跳过重复的固定元素
        if i > 0 && nums[i] == nums[i-1] {
            continue
        }
        
        target := -nums[i]
        l, r := i+1, n-1
        
        for l < r {
            sum := nums[l] + nums[r]
            if sum == target {
                result = append(result, []int{nums[i], nums[l], nums[r]})
                // 去重:跳过重复的左右指针
                for l < r && nums[l] == nums[l+1] { l++ }
                for l < r && nums[r] == nums[r-1] { r-- }
                l++
                r--
            } else if sum < target {
                l++
            } else {
                r--
            }
        }
    }
    return result
}

05:00 - 10:00 | 边界测试与修复

测试用例思维跑表:

用例 预期 代码能否通过
[-1,0,1,2,-1,-4] [[-1,-1,2],[-1,0,1]]
[0,0,0,0] [[0,0,0]] ✅ 去重逻辑正确
[-2,0,1,1,2] [[-2,0,2],[-2,1,1]]
[1,2,3,4] []
[] [] ✅ n<3返回空

发现潜在问题:当nums[i]已经大于0时,后面的数都大于0,三数之和不可能为0。

优化:添加提前终止条件

Go 复制代码
for i := 0; i < n-2; i++ {
    if nums[i] > 0 {
        break  // 后面的数都>=当前数,和不可能为0
    }
    // ... 原有逻辑
}

10:00 - 12:00 | 复杂度分析与Edge Cases文档化

复杂度:

时间:O(n²) --- 外层循环O(n) × 内层双指针O(n)

空间:O(1) --- 不计输出结果

Edge Cases清单:

  1. 数组长度 < 3 → 直接返回空

  2. 所有数 > 0 → 提前终止

  3. 所有数 < 0 → 需要遍历完

  4. 全0 → 只返回一组[0,0,0]

  5. 重复元素 → 三重去重(i层、l层、r层)

12:00 - 15:00 | 最终代码优化与提交

最终版本:

Go 复制代码
func threeSum(nums []int) [][]int {
    if len(nums) < 3 {
        return [][]int{}
    }
    
    sort.Ints(nums)
    result := make([][]int, 0)
    n := len(nums)
    
    for i := 0; i < n-2; i++ {
        // 剪枝:最小的数都大于0,后面不可能有解
        if nums[i] > 0 {
            break
        }
        // i层去重
        if i > 0 && nums[i] == nums[i-1] {
            continue
        }
        
        target := -nums[i]
        l, r := i+1, n-1
        
        for l < r {
            sum := nums[l] + nums[r]
            if sum == target {
                result = append(result, []int{nums[i], nums[l], nums[r]})
                // l层去重
                for l < r && nums[l] == nums[l+1] {
                    l++
                }
                // r层去重
                for l < r && nums[r] == nums[r-1] {
                    r--
                }
                l++
                r--
            } else if sum < target {
                l++
            } else {
                r--
            }
        }
    }
    return result
}

四、复盘

4.1 时间分布

阶段 用时 关键产出
读题破题 2分钟 确定排序+双指针方案
写代码框架 3分钟 核心循环+双指针逻辑
边界测试与修复 5分钟 三重去重+剪枝优化
复杂度分析 2分钟 文档化Edge Cases
最终优化 3分钟 提交前检查

4.2 关键决策记录

决策点 选择 理由
是否排序 排序 不改变结果,双指针前提
去重位置 i层、l层、r层三处 避免重复三元组
剪枝条件 nums[i] > 0 提前终止,常数优化
数据结构 切片[][]int Go惯用法

4.3 易错点对照

易错点 错误写法 正确写法
去重位置错误 只在最后去重 在移动指针时同步去重
越界访问 nums[i] == nums[i+1] i > 0 && nums[i] == nums[i-1]
漏掉零解 跳过所有重复 保留[0,0,0]这种情况

五、自测表

完成一道题后,用以下维度自评:

维度 优秀(5分) 及格(3分) 不及格(1分) 自评
破题速度 2分钟内出方案 5分钟内 >5分钟 5
代码正确性 一次通过 1-2次调试 >2次 4
边界覆盖 全部考虑 主要边界 遗漏关键边界 5
代码可读性 命名清晰、有注释 基本清晰 变量名混乱 4
复杂度分析 准确且优化 仅给出复杂度 不会分析 5

总分:23 → 可优化点:提交前快速跑3个测试用例

六、训练法

6.1 每日训练计划

阶段 内容 时长
热身 看一道已做过的题,口述思路 5分钟
快闪 新题限时15分钟 15分钟
复盘 对比最优解,记录差距 10分钟
归档 存入个人题库,标注易错点 5分钟

6.2 题型优先级

优先级 题型 考察重点 刷题占比
P0 数组、哈希表、双指针 基础数据结构 30%
P0 二叉树遍历 递归/迭代 20%
P1 动态规划 状态转移 20%
P1 滑动窗口、前缀和 连续子数组 15%
P2 图论、回溯 搜索剪枝 15%

6.3 15分钟倒计时心态法则

复制代码
0-3分钟:读题+确定方案
3-10分钟:写代码框架 + 核心逻辑
10-13分钟:补边界 + 去重 + 剪枝
13-15分钟:跑脑内测试用例 + 修正

铁律:超过3分钟还没思路,先写暴力解拿部分分,不要空着。

七、写在最后

算法快闪的核心不是难题怪题,而是在有限时间内把一道中等题完整地、高质量地写出来。

这道三数之和,涵盖了:

排序预处理

双指针算法

三重去重逻辑

剪枝优化

边界条件全覆盖

如果你能在15分钟内独立完成,说明你的思维速度和工程落地能力已经通过了实战检验。

相关推荐
qq_45239623几秒前
第十一篇:《资源管理:Requests/Limits、ResourceQuota、LimitRange》
算法·贪心算法
Tisfy4 分钟前
LeetCode 2095.删除链表的中间节点:两次遍历 / 一次遍历(快慢指针)
算法·leetcode·链表·题解·双指针
Irissgwe11 分钟前
AVL树详解
数据结构·c++·算法·二叉树·c·二叉搜索树·avl
凌波粒18 分钟前
LeetCode--131.分割回文串(回溯算法)
算法·leetcode·职场和发展
北域码匠41 分钟前
奇偶归并排序:并行计算的排序利器
数据结构·算法·c#·排序算法
成都易yisdong1 小时前
上海某平面坐标系与CGCS2000坐标互转详解(含全域拟合点、实战案例、保密规范)
大数据·人工智能·算法
2601_961845151 小时前
花生十三网课网盘|百度网盘|下载
数据结构·算法·链表·贪心算法·排序算法·线性回归·动态规划
快手技术1 小时前
征集令|快手探索者LLM-Rec挑战赛正式发布!
算法
Yvonne爱编码1 小时前
JAVA EE初阶---DAY 2 计算机网络
java·开发语言·计算机网络·算法·java-ee·php
JAVA9652 小时前
JAVA面试-JVM篇 02-G1垃圾收集器的工作原理是什么与CMS的区别
java·jvm·面试