Lee's Blog
  • 首页
  • 博客
  • 作品
  • 成长
  • 学习
  • 打榜
  • 练习
  • 关于
登录 / 注册
✦

保持联系

关注我的最新动态

GitHubbilibili

© 2026 Lee's Blog

学习路线

从入门到进阶,一步步点亮技能树

Lv.2
入门
100 XP
距下一级 200 XP
🏅初次打卡
总进度10 / 14 阶段完成 · 71%
01

LeetCode 刷题档案

已完成

账号公开数据快照,随学习进展更新

▸刷题数据画像(更新至 96 题)

我的 LeetCode 刷题档案(bailipa)

  • 账号:https://leetcode.cn/u/bailipa/
  • 数据抓取时间:2026-08-16(已登录抓取,含完整题单)

总览

  • 通过题目:96(简单 63 / 中等 31 / 困难 2)
  • 尝试未通过:1(LC1016 子串能表示从 1 到 N 数字的二进制串,中等)
  • 总提交:290 次(AC 203 / WA 62 / 重复提交 19)
  • 整体通过率:约 70%
  • 击败用户:综合 79.0%

专题分布(TOP 12)

数组×48、双指针×23、数学×19、字符串×18、二分查找×17、哈希表×15、排序×10、链表×9、滑动窗口×8、树×8、动态规划×7、模拟×7

里程碑

  • 2026-08-16:「新」动计划 · 编程入门 20/20 毕业 🎓(LC1470/LC867/LC1422/LC2586/LC852 收官)
  • 最近新增:LC1422 分割字符串的最大得分、LC2586 元音字符串数、LC852 山脉数组峰顶(拐点二分)

教学洞察

  1. 中等题通过率仍有提升空间(约 6 成)—— 后续教学以中等题为主
  2. 专题分布:数组(48)、双指针(23)、数学(19)、二分(17)、字符串(17)、哈希(15) —— 与学习路线一致
  3. 动态规划已接触(LC121/LC198/LC118/LC119)—— 可开 DP 专题
  4. 树/二叉树 8 题、DFS 7 题 —— 可系统开树专题
▸已刷题目全清单(96 题 AC)

已刷题目全清单(96 题 AC + 1 题尝试未过)

  • LC1 两数之和 · EASY · 数组/哈希表 · 做题
  • LC2 两数相加 · MEDIUM · 递归/链表/数学 · 做题
  • LC3 无重复字符的最长子串 · MEDIUM · 哈希表/字符串/滑动窗口 · 做题
  • LC9 回文数 · EASY · 数学 · 做题
  • LC11 盛最多水的容器 · MEDIUM · 贪心/数组/双指针 · 做题
  • LC13 罗马数字转整数 · EASY · 哈希表/数学/字符串 · 做题
  • LC14 最长公共前缀 · EASY · 字典树/数组/字符串 · 做题
  • LC15 三数之和 · MEDIUM · 数组/双指针/排序 · 做题
  • LC20 有效的括号 · EASY · 栈/字符串/括号序列 · 做题
  • LC21 合并两个有序链表 · EASY · 递归/链表 · 做题
  • LC26 删除有序数组中的重复项 · EASY · 数组/双指针 · 做题
  • LC27 移除元素 · EASY · 数组/双指针 · 做题
  • LC28 找出字符串中第一个匹配项的下标 · EASY · 双指针/字符串/字符串匹配/KMP 算法/Boyer–Moore 算法/扩展 KMP · 做题
  • LC33 搜索旋转排序数组 · MEDIUM · 数组/二分查找 · 做题
  • LC34 在排序数组中查找元素的第一个和最后一个位置 · MEDIUM · 数组/二分查找 · 做题
  • LC35 搜索插入位置 · EASY · 数组/二分查找 · 做题
  • LC42 接雨水 · HARD · 栈/数组/双指针/动态规划/单调栈 · 做题
  • LC49 字母异位词分组 · MEDIUM · 数组/哈希表/字符串/排序 · 做题
  • LC55 跳跃游戏 · MEDIUM · 贪心/数组/动态规划 · 做题
  • LC56 合并区间 · MEDIUM · 数组/排序/快速排序 · 做题
  • LC57 插入区间 · MEDIUM · 数组 · 做题
  • LC58 最后一个单词的长度 · EASY · 字符串 · 做题
  • LC59 螺旋矩阵 II · MEDIUM · 数组/矩阵/模拟 · 做题
  • LC66 加一 · EASY · 数组/数学 · 做题
  • LC67 二进制求和 · EASY · 位运算/数学/字符串/模拟 · 做题
  • LC69 x 的平方根 · EASY · 数学/二分查找/牛顿迭代法 · 做题
  • LC70 爬楼梯 · EASY · 记忆化/数学/动态规划 · 做题
  • LC82 删除排序链表中的重复元素 II · MEDIUM · 链表/双指针 · 做题
  • LC83 删除排序链表中的重复元素 · EASY · 链表 · 做题
  • LC88 合并两个有序数组 · EASY · 数组/双指针/排序 · 做题
  • LC92 反转链表 II · MEDIUM · 链表 · 做题
  • LC94 二叉树的中序遍历 · EASY · 栈/树/深度优先搜索/二叉树 · 做题
  • LC100 相同的树 · EASY · 树/深度优先搜索/广度优先搜索/二叉树 · 做题
  • LC101 对称二叉树 · EASY · 树/深度优先搜索/广度优先搜索 · 做题
  • LC104 二叉树的最大深度 · EASY · 树/深度优先搜索/广度优先搜索 · 做题
  • LC112 路径总和 · EASY · 树/深度优先搜索/广度优先搜索 · 做题
  • LC118 杨辉三角 · EASY · 数组/动态规划 · 做题
  • LC119 杨辉三角 II · EASY · 数组/动态规划 · 做题
  • LC121 买卖股票的最佳时机 · EASY · 数组/动态规划 · 做题
  • LC125 验证回文串 · EASY · 双指针/字符串 · 做题
  • LC136 只出现一次的数字 · EASY · 位运算/数组 · 做题
  • LC141 环形链表 · EASY · 哈希表/链表/双指针 · 做题
  • LC142 环形链表 II · MEDIUM · 哈希表/链表/双指针 · 做题
  • LC144 二叉树的前序遍历 · EASY · 栈/树/深度优先搜索 · 做题
  • LC145 二叉树的后序遍历 · EASY · 栈/树/深度优先搜索 · 做题
  • LC160 相交链表 · EASY · 哈希表/链表/双指针 · 做题
  • LC167 两数之和 II - 输入有序数组 · MEDIUM · 数组/双指针/二分查找 · 做题
  • LC189 轮转数组 · MEDIUM · 数组/数学/双指针 · 做题
  • LC198 打家劫舍 · MEDIUM · 数组/动态规划 · 做题
  • LC202 快乐数 · EASY · 哈希表/数学/双指针/Floyd 判圈算法 · 做题
  • LC206 反转链表 · EASY · 递归/链表 · 做题
  • LC209 长度最小的子数组 · MEDIUM · 数组/二分查找/前缀和/滑动窗口 · 做题
  • LC231 2 的幂 · EASY · 位运算/递归/数学 · 做题
  • LC239 滑动窗口最大值 · HARD · 队列/数组/滑动窗口/单调队列/堆(优先队列)/区间最值查询 · 做题
  • LC242 有效的字母异位词 · EASY · 哈希表/字符串/排序 · 做题
  • LC258 各位相加 · EASY · 数学/数论/模拟 · 做题
  • LC263 丑数 · EASY · 数学 · 做题
  • LC283 移动零 · EASY · 数组/双指针 · 做题
  • LC326 3 的幂 · EASY · 数学/递归 · 做题
  • LC344 反转字符串 · EASY · 双指针/字符串 · 做题
  • LC349 两个数组的交集 · EASY · 数组/哈希表/双指针/二分查找/排序 · 做题
  • LC387 字符串中的第一个唯一字符 · EASY · 队列/哈希表/字符串/计数 · 做题
  • LC584 寻找用户推荐人 · EASY · 数据库 · 做题
  • LC704 二分查找 · EASY · 数组/二分查找 · 做题
  • LC709 转换成小写字母 · EASY · 字符串 · 做题
  • LC713 乘积小于 K 的子数组 · MEDIUM · 数组/滑动窗口 · 做题
  • LC852 山脉数组的峰顶索引 · MEDIUM · 数组/二分查找/三分查找 · 做题
  • LC867 转置矩阵 · EASY · 数组/矩阵/模拟 · 做题
  • LC875 爱吃香蕉的珂珂 · MEDIUM · 数组/二分查找 · 做题
  • LC1004 最大连续1的个数 III · MEDIUM · 数组/二分查找/前缀和/滑动窗口 · 做题
  • LC1281 整数的各位积和之差 · EASY · 数学 · 做题
  • LC1385 两个数组间的距离值 · EASY · 数组/双指针/二分查找/排序 · 做题
  • LC1422 分割字符串的最大得分 · EASY · 字符串/前缀和 · 做题
  • LC1470 重新排列数组 · EASY · 数组 · 做题
  • LC1486 数组异或操作 · EASY · 位运算/数学 · 做题
  • LC1512 好数对的数目 · EASY · 数组/哈希表/数学 · 做题
  • LC1534 统计好三元组 · EASY · 数组/枚举 · 做题
  • LC1536 排布二进制网格的最少交换次数 · MEDIUM · 贪心/数组/矩阵 · 做题
  • LC1545 找出第 N 个二进制字符串中的第 K 位 · MEDIUM · 字符串/递归/模拟 · 做题
  • LC1757 可回收且低脂的产品 · EASY · 数据库 · 做题
  • LC2080 区间内查询数字的频率 · MEDIUM · 设计/线段树/数组/哈希表/二分查找 · 做题
  • LC2105 给植物浇水 II · MEDIUM · 数组/双指针/模拟 · 做题
  • LC2235 两整数相加 · EASY · 数学 · 做题
  • LC2236 判断根结点是否等于子结点之和 · EASY · 树/二叉树 · 做题
  • LC2300 咒语和药水的成功对数 · MEDIUM · 数组/双指针/二分查找/排序 · 做题
  • LC2413 最小偶倍数 · EASY · 数学/数论 · 做题
  • LC2469 温度转换 · EASY · 数学 · 做题
  • LC2529 正整数和负整数的最大计数 · EASY · 数组/二分查找/计数 · 做题
  • LC2563 统计公平数对的数目 · MEDIUM · 数组/双指针/二分查找/排序 · 做题
  • LC2586 统计范围内的元音字符串数 · EASY · 字符串 · 做题
  • LC2730 找到最长的半重复子字符串 · MEDIUM · 字符串/滑动窗口 · 做题
  • LC2824 统计和小于目标的下标对数目 · EASY · 数组/双指针/二分查找/排序 · 做题
  • LC2958 最多 K 个重复元素的最长子数组 · MEDIUM · 数组/哈希表/滑动窗口 · 做题
  • LC3090 每个字符最多出现两次的最长子字符串 · EASY · 哈希表/字符串/滑动窗口 · 做题
  • LC3833 统计主导元素下标数 · EASY · 数组/枚举 · 做题
  • LC3834 合并相邻且相等的元素 · MEDIUM · 栈/数组/模拟 · 做题
  • ⚠️ LC1016 子串能表示从 1 到 N 数字的二进制串 · MEDIUM · 尝试未通过 · 做题
▸「新」动计划 · 编程入门(20/20 ✅ 已毕业)

「新」动计划 · 编程入门(20/20 ✅ 已毕业)

  • 计划:https://leetcode.cn/studyplan/primers-list/
  • 状态:✅ 已完成(2026-08-16 结业)

全部 20 题

数组/位运算:LC2235 两整数相加、LC2469 温度转换、LC2413 最小偶倍数、LC1486 数组异或操作、LC1512 好数对的数目、LC1534 统计好三元组、LC231 2 的幂、LC326 3 的幂、LC263 丑数、LC1470 重新排列数组、LC867 转置矩阵、LC1422 分割字符串的最大得分、LC2586 统计范围内的元音字符串数 树:LC2236 判断根结点是否等于子结点之和 字符串/数学:LC709 转换成小写字母、LC258 各位相加、LC1281 整数的各位积和之差 二分:LC852 山脉数组的峰顶索引(毕业题,2026-08-16 AC) SQL:LC584 寻找用户推荐人、LC1757 可回收且低脂的产品

毕业收获(这个计划学到的)

  1. 增量更新思想:先统计一次全局,再逐刀增量更新(LC1422)
  2. Math.max 维护最大值:一行代替 if 判断
  3. String 操作三连:charAt 取字符、indexOf 判断包含、length() 带括号
  4. 编译错误三连:双引号包字符串、数字不带引号、方法要括号
  5. 二分第二模板:找拐点用 while (left < right) + right = mid(LC852)
  6. 二维数组入门:matrix[i][j]、行列对调(LC867)
▸LeetCode 热题 100 进度(2/100)

LeetCode 热题 100 进度(进行中)

  • 计划:https://leetcode.cn/studyplan/top-100-liked/
  • 开始:2026-08-16(新动计划毕业后进阶)
  • 规则:100 题(简单 20 / 中等 68 / 困难 12),主攻中等题

进度

  • 已刷:2 / 100
  • 已完成:LC1 两数之和(简单)、LC49 字母异位词分组(中等)
  • 下一题:LC128 最长连续序列(中等)

已掌握的哈希套路

  1. 计数模板(LC1512):getOrDefault 增量统计
  2. 两数之和模板(LC1):先查后存,HashMap 值→下标
  3. 排序归一模板(LC49):字符串排序 → 相同 key → 分组
02

Java 基础:类型转换

已完成

数字、字符串、字符之间的相互转换(刷题高频)

▸数字 ↔ 字符串 ↔ 字符 转换套路

数字 ↔ 字符串 ↔ 字符 转换套路

  1. int → String
String s = String.valueOf(num);
  1. String → char[] 字符数组
char[] arr = s.toCharArray();
  1. 数字字符 → int 数值(超级高频!)
int d = ch - '0';
  1. char[] → String
String res = new String(arr);
▸Java 刷题套路汇总清单(一共 16 个)

字符串‑数字转换(4)

  1. int转字符串 String.valueOf(num)
  2. 字符串拆字符数组 toCharArray()
  3. 字符数字转int ch-'0'
  4. char数组转回字符串 new String(arr)

字符串(1)

  1. toLowerCase() / +32大小写转换

数组(1)

  1. .length / .length() 区分

HashMap计数(2)

  1. getOrDefault 计数自增
  2. 先统计、后更新的顺序套路

数学(1)

  1. Math.abs()

双指针(3)

  1. 左右对撞指针(反转字符串)
  2. 快慢指针判环
  3. 快慢指针找环入口

二分(2)

  1. 基础二分模板
  2. 带开关的边界二分

链表(1)

  1. 链表遍历 ptr = ptr.next

SQL(2)

  1. NULL判断、AND OR筛选
03

Java 字符串与数组

已完成

字符串与数组的常用操作

▸字符串操作与数组套路

字符串操作

  1. 大写转小写
s.toLowerCase()

手动版公式:c + 32(前提先判断 c >= 'A' && c <= 'Z')

数组套路

  1. 数组长度
arr.length      //数组,无括号
str.length()    //字符串,带括号
▸LC1470 重新排列数组(交错填格模板)

LC1470 重新排列数组(新动计划第 16/20 题)

  • 题目链接:https://leetcode.cn/problems/shuffle-the-array/
  • 难度:简单 | 专题:数组
  • 一句话思路:交错重排 = 偶数位填前半段、奇数位填后半段,一次循环填两格
  • 掌握程度:已独立 AC ✅

完整可提交代码

class Solution {
    public int[] shuffle(int[] nums, int n) {
        int[] result = new int[2 * n];        // 新数组
        for (int i = 0; i < n; i++) {
            result[2 * i] = nums[i];          // 偶数位 ← 前半段第 i 个
            result[2 * i + 1] = nums[n + i];  // 奇数位 ← 后半段第 i 个
        }
        return result;
    }
}

具象推演(nums = [2,5,1,3,4,7], n = 3)

i result[2i]=nums[i] result[2i+1]=nums[n+i] 结果
0 result[0]=2 result[1]=3 [2,3,0,0,0,0]
1 result[2]=5 result[3]=4 [2,3,5,4,0,0]
2 result[4]=1 result[5]=7 [2,3,5,4,1,7] ✅

踩坑记录(本次学习重点)

  1. ❌ 交换法不行:交错重排不是两两交换,交换会把元素放错家(7 跑到位置 1)
  2. ❌ i <= n 越界:数组 2n 个元素,最大索引 2n-1;nums[l+i+1] 在 i=n-1 时访问 nums[2n] 崩溃
  3. ✅ 边界公式:i 从 0 开始数 n 次 → 条件永远写 i < n
  4. ✅ 新数组 + 填空:2*i 是偶数位、2*i+1 是奇数位,正好交错

语法要点

  • int[] result = new int[2 * n] 创建数组,格子初始为 0
  • 数组索引从 0 开始,访问 nums.length 个元素时索引是 0 ~ length-1
▸LC867 转置矩阵(二维数组入门)

LC867 转置矩阵(新动计划第 17/20 题)

  • 题目链接:https://leetcode.cn/problems/transpose-matrix/
  • 难度:简单 | 专题:矩阵 / 二维数组
  • 一句话思路:转置 = 行变列,下标对调 result[j][i] = matrix[i][j]
  • 掌握程度:已独立 AC ✅(二维数组入门题)

完整可提交代码

class Solution {
    public int[][] transpose(int[][] matrix) {
        int rows = matrix.length;         // 原矩阵行数 m
        int cols = matrix[0].length;      // 原矩阵列数 n

        int[][] result = new int[cols][rows];  // 转置后行列对调!

        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                result[j][i] = matrix[i][j];  // 下标对调
            }
        }
        return result;
    }
}

踩坑记录

  1. 新数组行列对调:new int[cols][rows],写反了越界
  2. 下标对调:result[j][i] 不是 result[i][j]
  3. 二维数组语法:matrix.length 是行数,matrix[0].length 是列数

语法要点(二维数组入门)

  • int[][] matrix = {{1,2,3},{4,5,6}} 外层行、内层列
  • matrix[i][j]:第一个下标是行,第二个是列
  • 记忆:转置像换电影院座位——排和号对调
▸LC1422 分割字符串的最大得分(增量更新+Math.max)

LC1422 分割字符串的最大得分(新动计划第 18/20 题)

  • 题目链接:https://leetcode.cn/problems/maximum-score-after-splitting-a-string/
  • 难度:简单 | 专题:字符串 / 前缀增量
  • 一句话思路:先数全串 1 的个数,再逐刀切,每刀只调整一个字符(0 进左计数++ / 1 出右计数--)
  • 掌握程度:已独立 AC ✅

完整可提交代码

class Solution {
    public int maxScore(String s) {
        int n = s.length();
        int totalOnes = 0;
        for (int i = 0; i < n; i++) {
            if (s.charAt(i) == '1') totalOnes++;
        }
        int max = 0;
        int leftZeros = 0;
        int rightOnes = totalOnes;
        for (int i = 0; i < n - 1; i++) {   // i 只到 n-2:右边必须非空
            if (s.charAt(i) == '0') leftZeros++;
            else rightOnes--;
            max = Math.max(max, leftZeros + rightOnes);  // 亮点:max 直接维护
        }
        return max;
    }
}

核心技巧(这次学到的)

  1. 增量更新:暴力是每个分割点重新数一遍 O(n²);优化后每刀只处理一个字符的归属变化 O(n)
  2. Math.max 维护最大值:max = Math.max(max, 当前值) 一行搞定,省掉 if 判断
  3. 与 LC1512 同源:先统计一次全局,再增量更新(先统计后更新的升级版)

易错点

  • i < n - 1:右边必须留至少 1 个字符,i 不能到 n-1
  • 先更新计数再算分:这一刀切的字符归属要先"翻"过来
▸高频踩坑:数组 .length vs 字符串 .length()

高频踩坑:数组 length vs 字符串 length()

踩坑记录:LC1470、LC1422 都栽在这里 —— 数组 .length 不带括号,字符串 .length() 带括号

完整规则

东西 写法 原因
数组 arr.length(无括号) 数组是 Java 语言内建类型,length 是属性(字段)
字符串 String s.length()(有括号) String 是普通类,length() 是方法
ArrayList list.size()(有括号) 普通类,方法
HashMap / HashSet map.size()(有括号) 普通类,方法
字符数组转回 new String(arr)(无括号) 构造器语法,不是取长度

为什么数组特殊?

数组不是"类"——它是 Java 语言层面的内建类型(和 int、double 同级),length 是 JVM 里直接存的字段,不需要调用方法。而 String、ArrayList 是正经的类,一切通过方法访问。

一口诀

只有数组的 length 是属性,其他一切"长度/大小"都是方法

拿不准时:先默认带括号,只有面对数组才去掉。

同类"一对多"混淆(预防)

  • 数组取元素 arr[i](下标语法)vs 字符串取字符 s.charAt(i)(方法)
  • s.toCharArray() 返回数组 → 之后用 .length(无括号)
  • 数组 new int[5] 创建 vs 字符串 new String(arr) 转换

记忆锚点

  • String.valueOf(num) → String(方法,有括号)
  • s.toCharArray() → char[](方法,有括号)
  • 一旦到了 char[] arr,取长度就是 arr.length(数组,无括号)

链条记忆:方法返回数组的那一刻,length 就变成了属性。

▸LC2586 统计范围内的元音字符串数(indexOf判断+编译错误三连)

LC2586 统计范围内的元音字符串数(新动计划第 19/20 题)

  • 题目链接:https://leetcode.cn/problems/count-the-number-of-vowel-strings-in-range/
  • 难度:简单 | 专题:字符串
  • 一句话思路:顺序遍历区间 [left, right],统计"首尾都是元音"的单词
  • 掌握程度:已独立 AC ✅(编译错误三连修正后通过)

完整可提交代码

class Solution {
    public int vowelStrings(String[] words, int left, int right) {
        String vowels = "aeiou";
        int count = 0;
        for (int i = left; i <= right; i++) {
            String word = words[i];
            char first = word.charAt(0);
            char last = word.charAt(word.length() - 1);
            if (vowels.indexOf(first) != -1 && vowels.indexOf(last) != -1) {
                count++;
            }
        }
        return count;
    }
}

套路

  1. 判断字符是否元音:"aeiou".indexOf(ch) != -1(找到了返回位置,找不到返回 -1)
  2. String 取字符用 charAt(i),Java 的 String 不是字符数组,不能下标访问
  3. 遍历下标区间 → for 循环(不要用双指针从两端夹,会漏中间元素)
  4. 首尾都满足条件 → &&,不是 ||

踩坑:编译错误三连(本次重点)

  1. 单引号 vs 双引号:字符串必须双引号 "aeiou",单引号只能包一个字符 'a'
  2. 字符 vs 数字:int count = 0(数字不带引号);'0' 是字符,值是 ASCII 48
  3. 漏括号:word.length() 是方法必须带括号(数组 .length 才不带)
  4. 变量名拼写要一致(vowles vs vowels 会报"找不到符号")

口诀:双引号包字符串,单引号包单个字符;数字不带引号,字符才带引号

04

Java 集合:HashMap 计数

已完成

刷题高频的哈希表计数模板(LC1512)

▸哈希表计数模板

哈希表计数模板(LC1512)

  1. 频次+1 标准一行写法
cnt.put(num, cnt.getOrDefault(num,0)+1);

拆解底层:判断是否存在、取旧值、+1、存回去

  1. 先累加再更新(好数对顺序不能颠倒)
res += cnt.getOrDefault(num,0);
cnt.put(num, cnt.getOrDefault(num,0)+1);
▸HashMap API 速记(三件套 + for 循环选择)

HashMap API 速记(哈希表三件套)

补课来源:热题 100 第一题 twoSum 复习时暴露的 API 记忆问题

三件套(背下来)

map.containsKey(key)   // 判断 key 在不在 → true/false(拼写:contains KEY!)
map.get(key)           // 取 key 对应的 value
map.put(key, value)    // 存 key -> value

常见错误

  1. contains 拼错:是 containsKey,不是 countains / contains
  2. 数组没有这些方法:HashMap 是 Map 接口的实现,数组是 int[],两者完全不同
  3. 声明:Map<Integer, Integer> map = new HashMap<>()(key 和 value 都要写类型)

for-each vs 普通 for 的选择

场景 用哪个 例子
需要下标 普通 for for (int i = 0; i < arr.length; i++) twoSum 返回下标
只要值 for-each for (int num : arr) 求和、计数

记忆:要下标 → 普通 for;不要下标 → for-each

哈希模板回顾(LC1 / LC1512 通用)

// 先查(读旧状态),后存(写新状态)——顺序不能反!
if (map.containsKey(x)) { ... }
map.put(nums[i], i);
▸LC49 字母异位词分组(排序归一模板+新API清单)

LC49 字母异位词分组(热题 100,2026-08-16)

  • 题目链接:https://leetcode.cn/problems/group-anagrams/
  • 难度:中等 | 专题:哈希表 + 排序归一
  • 一句话思路:字符串排序结果当 key,相同的归为一组
  • 掌握程度:已 AC(照抄,新 API 需复习巩固)

完整代码

import java.util.*;

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        Map<String, List<String>> map = new HashMap<>();
        for (String word : strs) {
            char[] arr = word.toCharArray();
            Arrays.sort(arr);
            String key = new String(arr);
            if (!map.containsKey(key)) {
                map.put(key, new ArrayList<>());
            }
            map.get(key).add(word);
        }
        return new ArrayList<>(map.values());
    }
}

本次新 API 清单(需复习)

新 API 说明
Arrays.sort(arr) 数组原地排序(字符串三步走第二步)
new ArrayList<>() 创建空列表(分组容器)
list.add(x) 往列表末尾加元素
map.values() 取出所有分组,转成 List 返回
Map<String, List<String>> 声明:key=字符串,value=字符串列表

核心套路:排序归一

判断一组东西"本质上是否相同" → 排个序 → 排序结果当 key

与 LC242 验证异位词同源(那边用计数当 key,这边用排序当 key,都行)

复习计划

明天不看答案,从空文件重写一遍——写不出的部分就是还没记住的 API,单独背。

05

Java 数学工具

已完成

常用数学方法

▸数学工具方法

数学工具方法

  1. 取绝对值
Math.abs(x)
06

算法:双指针

已完成

对撞指针 + 快慢指针

▸双指针模板

双指针模板

  1. 反转数组左右指针
int left = 0, right = s.length-1;
while(left < right){
    swap
    left++;right--;
}
  1. 快慢指针链表(141、142 环形链表)
  • 检测环:slow 一次 1 步,fast 一次 2 步
  • 找环入口:相遇之后,一个指针从头、一个从相遇点,同速走
▸LC852 山脉数组的峰顶索引(拐点二分·毕业题)

LC852 山脉数组的峰顶索引(新动计划第 20/20 题 · 毕业题)

  • 题目链接:https://leetcode.cn/problems/peak-index-in-a-mountain-array/
  • 难度:中等 | 专题:二分查找(拐点二分)
  • 一句话思路:比较相邻元素判断上下坡,用 while (left < right) + right = mid 模板收缩到峰顶
  • 掌握程度:已独立 AC ✅(新动计划毕业题)

完整可提交代码

class Solution {
    public int peakIndexInMountainArray(int[] arr) {
        int left = 0, right = arr.length - 1;
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (arr[mid] < arr[mid + 1]) {
                left = mid + 1;   // 上坡:峰顶在右边,mid 可排除
            } else {
                right = mid;      // 下坡:mid 可能就是峰顶,不能排除!
            }
        }
        return left;
    }
}

核心:为什么 right = mid 不是 mid - 1

能不能证明 mid 不是答案?

  • 上坡 arr[mid] < arr[mid+1]:mid 右边有更大的,mid 不可能是峰顶 → 排除 → left = mid + 1
  • 下坡 arr[mid] > arr[mid+1]:mid 可能就是峰顶(如 [0,1,2,1,0] 中 mid=2) → 不能排除 → right = mid

标准二分(找值)里 mid 已被验证"不是 target",所以敢 mid ± 1;拐点二分里下坡的 mid 可能是答案,只能收缩不能跳过。

二分武器库(现在有两把了)

找值二分(LC704/35/34) 拐点二分(LC852)
目标 找 target 找转折点/峰顶
循环 while (left <= right) while (left < right)
更新 left = mid+1 / right = mid-1 left = mid+1 / right = mid
排除逻辑 mid 已验证非答案 上坡排除 mid,下坡保留 mid
结束 left 越过 right left == right 汇合

记忆锚点

  • 找值 → <= + 两边都跳过 mid(排除式)
  • 找拐点 → < + 一边跳过、一边保留 mid(保留式)
  • 判断标准:能不能证明 mid 不是答案
07

算法:二分查找

已完成

标准二分 + 左右边界二分(704、35、34)

▸二分查找基础模板

二分查找基础模板(704、35、34)

  1. 标准二分
int left=0, right=nums.length-1;
while(left <= right){
    int mid = (left+right)/2;
}
  1. 左右边界二分开关模板(boolean lower)
08

链表基础

已完成

链表遍历基础

▸链表遍历

链表基础

  1. 从头遍历链表
ListNode ptr = head;
while (ptr != null) {
    // 处理当前节点
    ptr = ptr.next;
}
09

SQL 入门

进行中

刚接触的 SQL 查询套路

▸SQL 两条套路

SQL 套路(2 条)

  1. NULL 不能用 !=,必须用 IS NULL
  2. 多条件筛选:AND 同时满足 / OR 满足其一
010

滑动窗口模板

未开始

后续刷题目标

011

两数之和哈希查找

已完成

后续刷题目标

▸LC1 两数之和

LC1 两数之和

  • 题目链接:https://leetcode.cn/problems/two-sum/
  • 难度:简单 | 专题:哈希表
  • 一句话思路:边走边记,等另一半出现(target - num)

完整可提交代码

import java.util.HashMap;
import java.util.Map;

class Solution {
    public int[] twoSum(int[] nums, int target) {
        // map 记录:值 -> 下标(先查后存)
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            int complement = target - nums[i]; // 需要的另一半
            if (map.containsKey(complement)) {
                return new int[]{map.get(complement), i};
            }
            map.put(nums[i], i); // 没等到,先把自己记下来
        }
        return new int[]{}; // 题目保证有解,走不到这里
    }
}

具象推演

nums = [2, 7, 11, 15], target = 9

步骤 当前数字 需要的另一半 表里有吗? 动作
i=0 2 9-2=7 否(空表) 记 2 → 0
i=1 7 9-7=2 有!(2→0) 返回 [0, 1]

高频坑点

  1. 必须先查、后存:先 put 再查会命中自己 —— nums=[3,3], target=6 时错误返回 [1,1](同一个元素用两次)
  2. 与 LC1512 同一套路:先读旧状态,再写新状态

掌握程度

  • 已理解 ✅(待独立 AC 后勾选)
012

反转链表模板

未开始

后续刷题目标

013

第1周:Java环境与基础语法

进行中

Java后端实习准备第1周(2026-09-01 ~ 09-07):搭建JDK17+IDEA开发环境,跑通HelloWorld,掌握基础语法(变量、数据类型、运算符、流程控制、循环、数组、方法)。目标:能独立写九九乘法表与调用方法。

▸Day2 · 基础语法五连击(5/5 ✅)

今天完成了第1周基础语法的5个练习,全部跑通并验证:

  1. 运算符:OperatorsDemo.java 覆盖算术(+ - * / %)、关系(> < == !=)、逻辑(&& || !)、赋值(+= -=)、三元(a>b?a:b),注意整数除法截断(10/3=3)与%取余。
  2. 流程控制:if/else + switch 按分数区间输出等级(优/良/及格/不及格),记住 switch 每个 case 要 break 防穿透。
  3. 循环:while 实现 1~100 求和(sum+=i 累加器模板)。
  4. 数组:int 数组 for 遍历求和 + 找最大值(max 滚动比较),注意 i<arr.length 防越界。
  5. 方法:定义有参有返回值方法(计算矩形面积)并在 main 调用。

收获:首次把运算符/流程/循环/数组/方法整条链路串起来跑通,理解了"声明→计算→打印"的代码组织方式。下一步自测九九乘法表,然后进入面向对象。

▸第1周验收通过 · 提前进入第2周

第1周语法提前完成并通过独立验收:能不看笔记写出九九乘法表(嵌套for循环)+ 带返回值的求和/矩形面积方法并调用,确认第1周真完成(不只是"看过")。推进节奏调整为"自由推进"模式:每学一个主题独立写出来验收通过再继续。现在提前进入第2周面向对象(类/封装/继承/多态/接口/异常/String),并补学Git把项目推到GitHub。

▸Day2晚 · 面向对象起步 + Git 上线(5/5 ✅)

第1周下半场(09-02晚)追加,进度 5/5:①通过独立验收(九九乘法表+带返回值方法求和),确认语法是真掌握;②进入面向对象:定义 Student 类(属性+构造方法)、new 对象并打印;③完成封装:字段改 private + getter/setter + setter 校验年龄非负,理解了"外部不能直接改字段、访问要过一道门"的封装思想;④C线算法刷题恢复手感;⑤用 Git 把 helloworld 项目推到 GitHub(github.com/Bailipa/Java-learning),中途解决分支名 master/main 和 gh 代理(127.0.0.1:7897)两个坑。收获:完成从"语法"到"面向对象+版本控制"的跨越。

▸回归日 · 面向对象·继承独立验收通过(4/4 全勤)

09-02 后摆烂几天,今天鼓起勇气回归。完成:①面向对象·继承——独立写出 Animal(父类, name/eat) + Dog/Cat(extends 继承 + @Override 覆写 eat(),Dog 加 bark、Cat 加 meow),TestAnimal 编译运行通过,这是第2周面向对象的第一站;②C线算法刷数组/链表 1-2 题恢复手感;③用 Git 推到 GitHub Bailipa/Java-learning(顺带加了 .gitignore 排除 .class);④博客回归打卡 + 发文《我回来了》记录心路。收获:真正弄懂了 extends、super(name)、@Override 覆写、多态地基;也重新想通了一个点——对爱"做东西"的自己,把学习当"做出来能跑"比"背会"更有归属感。

014

第1周:第1周

已完成

第1周学习目标:第1周

▸2026-09-02 打卡

完成:

  • 第1周验收:独立写九九乘法表 + 带返回值方法求和(已通过)
  • 面向对象:学类与对象+构造方法,定义 Student 类并创建对象
  • 面向对象:学封装(private + getter/setter),给 Student 加字段访问控制
  • C线算法:刷 1-2 题(数组/链表专题,恢复手感)
  • 用 Git 把 学习中创建的java文件推到 GitHub (由 dsh 计划面板自动记录)
▸2026-09-02 打卡

完成:

  • 第1周验收:独立写九九乘法表 + 带返回值方法求和(已通过)
  • 面向对象:学类与对象+构造方法,定义 Student 类并创建对象
  • 面向对象:学封装(private + getter/setter),给 Student 加字段访问控制
  • C线算法:刷 1-2 题(数组/链表专题,恢复手感)
  • 用 Git 把 学习中创建的java文件推到 GitHub (由 dsh 计划面板自动记录)
▸2026-09-02 打卡

完成:

  • 第1周验收:独立写九九乘法表 + 带返回值方法求和(已通过)
  • 面向对象:学类与对象+构造方法,定义 Student 类并创建对象
  • 面向对象:学封装(private + getter/setter),给 Student 加字段访问控制
  • C线算法:刷 1-2 题(数组/链表专题,恢复手感)
  • 用 Git 把 学习中创建的java文件推到 GitHub (由 dsh 计划面板自动记录)
▸2026-09-07 打卡

完成:

  • 面向对象·继承:定义 Animal 父类(如 name/eat),写 Dog、Cat 继承它并覆写方法,独立写出来能编译运行
  • C线算法:刷1-2题(数组/链表专题)恢复手感
  • 跑通后把 java 文件用 Git 推到 GitHub(记得先 export HTTPS_PROXY=http://127.0.0.1:7897)
  • 在博客学习页打个今天回归的卡 (由 dsh 计划面板自动记录)