☰
Java LeetCode Hot100 刷题学习指南
2026/10/12 21:11:57 网站建设 项目流程

Java LeetCode Hot100 刷题学习指南

刷题这件事,最怕的不是题目难,而是漫无目的地刷。本文档将带你从零基础开始,用六天时间掌握 Hot100 中最核心的算法套路和模板,让你真正做到"刷一题会一类"。


一、学习方法论:先背模板,再谈理解

作为新手,你的目标不是"发明算法",而是"识别题型并套用模板"。记住:

80% 的算法题 = 固定模板 + 变量替换

正确的学习顺序:

  1. 背模板:把核心代码写到肌肉记忆
  2. 抄题目:照葫芦画瓢完成第一道题
  3. 理解原理:搞清楚模板为什么能解决问题
  4. 举一反三:用同一模板解决类似问题

二、Day 1:数组 + 哈希表 + 双指针(基础打底)

这是最基础也最重要的一天,几乎所有题目都会用到这些技巧。

2.1 数组(Array)

数组是一切的起点,记住一个遍历模板就够了:

// 正序遍历for(inti=0;i<nums.length;i++){// 处理 nums[i]}// 倒序遍历(用于原地修改)for(inti=nums.length-1;i>=0;i--){// 处理 nums[i]}
前缀和(PreSum)—— 快速算区间和
int[]pre=newint[nums.length+1];for(inti=0;i<nums.length;i++){pre[i+1]=pre[i]+nums[i];}// 求 nums[i] 到 nums[j] 的和intsum=pre[j+1]-pre[i];
差分数组(Diff)—— 区间统一修改
int[]diff=newint[nums.length];diff[0]=nums[0];for(inti=1;i<nums.length;i++){diff[i]=nums[i]-nums[i-1];}// 给 [l, r] 加 valdiff[l]+=val;if(r+1<diff.length)diff[r+1]-=val;

记忆口诀:区间统一加,差分两头掐。左端加,右端减,最后前缀和还原。

2.2 哈希表(HashMap)

哈希表的核心是"空间换时间",把 O(n) 的查找变成 O(1)。

基础操作(必背)
Map<Integer,Integer>map=newHashMap<>();map.put(key,value);// 放数据map.get(key);// 取数据(不存在返回 null)map.containsKey(key);// 判断有没有map.getOrDefault(key,0);// 取数据,没有就给默认值(高频!)
三种高频用法
用法模板典型题
计数map.put(num, map.getOrDefault(num, 0) + 1)两数之和、字母异位词
存索引map.put(nums[i], i)两数之和
分组map.computeIfAbsent(key, k -> new ArrayList<>()).add(value)字母异位词分组

重点:computeIfAbsent是 Java 8 新增方法,当 key 不存在时才创建新对象,避免重复创建。

2.3 双指针(Two Pointers)

双指针的本质是"用两个变量代替两层循环",把 O(n²) 优化成 O(n)。

快慢指针(原地修改)
intslow=0;for(intfast=0;fast<nums.length;fast++){if(nums[fast]!=val){nums[slow++]=nums[fast];}}returnslow;

记忆口诀:快指针找非零,慢指针填坑。

对撞指针(有序数组)
intleft=0,right=nums.length-1;while(left<right){intsum=nums[left]+nums[right];if(sum==target)returnnewint[]{left+1,right+1};elseif(sum<target)left++;elseright--;}
滑动窗口(进阶)
Map<Character,Integer>window=newHashMap<>();intleft=0,right=0;while(right<s.length()){charc=s.charAt(right);right++;window.put(c,window.getOrDefault(c,0)+1);while(需要收缩窗口){chard=s.charAt(left);left++;window.put(d,window.get(d)-1);}}

2.4 Day 1 必刷题目

题目类型难度
1. 两数之和哈希表🟢
283. 移动零快慢指针🟢
242. 有效的字母异位词哈希表🟢
11. 盛最多水的容器对撞指针🟡
15. 三数之和双指针 + 去重🟡
3. 无重复字符的最长子串滑动窗口🟡

三、Day 2:链表(代码短但易出错)

链表是面试必考项,核心是指针操作和边界处理。

3.1 链表结构

classListNode{intval;ListNodenext;ListNode(intx){val=x;}}

3.2 五大套路

套路一:虚拟头节点(删除题必备)
ListNodedummy=newListNode(-1);dummy.next=head;ListNodecur=dummy;

为什么要用虚拟头?避免处理头节点为空的特殊情况。

套路二:反转链表(面试之王)
ListNodeprev=null;ListNodecur=head;while(cur!=null){ListNodenext=cur.next;cur.next=prev;prev=cur;cur=next;}returnprev;

记忆口诀:保存下一个,反转指针,移动 prev 和 cur。

套路三:快慢指针(找中点/判环)
ListNodeslow=head,fast=head;while(fast!=null&&fast.next!=null){slow=slow.next;fast=fast.next.next;}// slow 就是中点
套路四:删除倒数第 N 个节点
ListNodedummy=newListNode(0,head);ListNodefast=dummy,slow=dummy;for(inti=0;i<n;i++)fast=fast.next;while(fast.next!=null){fast=fast.next;slow=slow.next;}slow.next=slow.next.next;returndummy.next;

3.3 Day 2 必刷题目

题目类型难度
206. 反转链表指针翻转🟢
21. 合并两个有序链表递归/迭代🟢
19. 删除链表的倒数第 N 个节点快慢指针🟡
141. 环形链表快慢指针🟢
25. K 个一组翻转链表进阶🔴

四、Day 3:栈 / 队列 / 字符串 / 滑动窗口

4.1 栈(Stack)—— 后进先出

Stack<Integer>stack=newStack<>();stack.push(x);// 入栈stack.pop();// 出栈stack.peek();// 查看栈顶stack.isEmpty();// 是否为空
经典应用:有效的括号
Stack<Character>stack=newStack<>();for(charc:s.toCharArray()){if(c=='(')stack.push(')');elseif(c=='{')stack.push('}');elseif(c=='[')stack.push(']');elseif(stack.isEmpty()||stack.pop()!=c)returnfalse;}returnstack.isEmpty();

4.2 队列(Queue)—— 先进先出

Queue<Integer>queue=newLinkedList<>();queue.offer(x);// 入队queue.poll();// 出队queue.peek();// 查看队首

4.3 字符串操作

s.charAt(i);// 获取第 i 个字符s.substring(i,j);// 截取 [i, j)s.toCharArray();// 转字符数组s.equals(other);// 比较内容(别用 ==)s.length();// 长度

4.4 Day 3 必刷题目

题目类型难度
20. 有效的括号栈🟢
155. 最小栈栈设计🟢
739. 每日温度单调栈🟡
3. 无重复字符的最长子串滑动窗口🟡
76. 最小覆盖子串滑动窗口🔴

五、Day 4:二叉树 + DFS/BFS(重中之重)

二叉树是算法世界的"通用货币",掌握它几乎能解决一半的面试题。

5.1 二叉树结构

classTreeNode{intval;TreeNodeleft;TreeNoderight;TreeNode(intx){val=x;}}

5.2 四种遍历方式

前序遍历(根 → 左 → 右)
voidpreorder(TreeNoderoot){if(root==null)return;System.out.println(root.val);preorder(root.left);preorder(root.right);}
中序遍历(左 → 根 → 右)
voidinorder(TreeNoderoot){if(root==null)return;inorder(root.left);System.out.println(root.val);inorder(root.right);}
后序遍历(左 → 右 → 根)
voidpostorder(TreeNoderoot){if(root==null)return;postorder(root.left);postorder(root.right);System.out.println(root.val);}
层序遍历(BFS)
voidlevelOrder(TreeNoderoot){Queue<TreeNode>queue=newLinkedList<>();queue.offer(root);while(!queue.isEmpty()){TreeNodenode=queue.poll();System.out.println(node.val);if(node.left!=null)queue.offer(node.left);if(node.right!=null)queue.offer(node.right);}}

5.3 三大核心思想

思想一:递归 = 相信它能搞定子树
intmaxDepth(TreeNoderoot){if(root==null)return0;returnMath.max(maxDepth(root.left),maxDepth(root.right))+1;}
思想二:回溯(路径问题)
path.add(root.val);dfs(root.left);path.remove(path.size()-1);
思想三:分治
returnmerge(leftResult,rightResult);

5.4 Day 4 必刷题目

题目类型难度
104. 二叉树的最大深度递归🟢
100. 相同的树递归比较🟢
101. 对称二叉树递归比较🟢
102. 二叉树的层序遍历BFS🟡
236. 二叉树的最近公共祖先后序遍历🟡

六、Day 5:二分查找 + 回溯 + 贪心

6.1 二分查找

二分查找的核心是"每次排除一半",前提是数组有序。

intleft=0,right=nums.length-1;while(left<=right){intmid=left+(right-left)/2;// 防止溢出if(nums[mid]==target)returnmid;elseif(nums[mid]<target)left=mid+1;elseright=mid-1;}return-1;

记忆口诀:左闭右闭<=,左闭右开<,mid 别溢出。

6.2 回溯(Backtracking)

回溯的本质是"尝试所有可能,不行就撤回"。

voidbacktrack(路径,选择列表){if(满足结束条件){result.add(路径);return;}for(选择:选择列表){做选择;backtrack(路径,选择列表);撤销选择;}}

6.3 贪心(Greedy)

贪心的核心是"每一步都选最优,不回头"。

// 例子:跳跃游戏intmaxReach=0;for(inti=0;i<nums.length;i++){if(i>maxReach)returnfalse;maxReach=Math.max(maxReach,i+nums[i]);}returntrue;

6.4 Day 5 必刷题目

题目类型难度
33. 搜索旋转排序数组二分🟡
704. 二分查找基础🟢
46. 全排列回溯🟡
78. 子集回溯🟡
55. 跳跃游戏贪心🟡

七、Day 6:动态规划(DP)

动态规划是算法中的"核武器",掌握它能解决最难的问题。

7.1 DP 解题框架

  1. 定义状态:dp[i]表示什么?
  2. 状态转移方程:dp[i] = f(dp[i-1], dp[i-2], ...)
  3. 初始化:dp[0],dp[1]等于什么?
  4. 遍历顺序:从前到后还是从后到前?

7.2 常见 DP 类型

一维 DP
// 爬楼梯:dp[i] = dp[i-1] + dp[i-2]int[]dp=newint[n+1];dp[0]=1;dp[1]=1;for(inti=2;i<=n;i++){dp[i]=dp[i-1]+dp[i-2];}
二维 DP
// 最小路径和int[][]dp=newint[m][n];dp[0][0]=grid[0][0];for(inti=0;i<m;i++){for(intj=0;j<n;j++){dp[i][j]=Math.min(dp[i-1][j],dp[i][j-1])+grid[i][j];}}

7.3 Day 6 必刷题目

题目类型难度
53. 最大子数组和一维 DP🟢
70. 爬楼梯一维 DP🟢
198. 打家劫舍一维 DP🟡
62. 不同路径二维 DP🟡
72. 编辑距离二维 DP🔴

八、六天速通计划总结

天数内容核心模板
Day 1数组 + 哈希表 + 双指针遍历、计数、快慢指针、滑动窗口
Day 2链表反转、虚拟头、快慢指针
Day 3栈/队列/字符串栈模拟、滑动窗口框架
Day 4二叉树 + DFS/BFS递归、BFS、后序遍历
Day 5二分 + 回溯 + 贪心二分模板、回溯框架、贪心策略
Day 6动态规划DP 四步框架

九、常用方法速查

9.1 HashMap 常用方法

方法说明
put(K key, V value)插入键值对
get(Object key)根据 key 获取 value
containsKey(Object key)判断是否包含 key
getOrDefault(Object key, V defaultValue)获取 value,不存在返回默认值
computeIfAbsent(K key, Function remappingFunction)key 不存在时创建并返回
size()返回元素个数

9.2 数组常用操作

操作代码
遍历for (int i = 0; i < nums.length; i++)
长度nums.length
复制Arrays.copyOf(nums, length)
排序Arrays.sort(nums)
查找Arrays.binarySearch(nums, target)

9.3 字符串常用操作

操作代码
长度s.length()
获取字符s.charAt(i)
截取s.substring(start, end)
转数组s.toCharArray()
比较s.equals(other)
拼接s.concat(other)或s + other

十、新手避坑指南

10.1 Java 泛型不支持基本类型

Map<int,int>map;// ❌ 错误!Map<Integer,Integer>map;// ✅ 正确

10.2 字符串比较别用 ==

if(s1==s2){}// ❌ 比较引用if(s1.equals(s2)){}// ✅ 比较内容

10.3 数组越界检查

// 正确做法if(i>=0&&i<nums.length){...}

10.4 递归必须有终止条件

voiddfs(TreeNoderoot){if(root==null)return;// 终止条件dfs(root.left);dfs(root.right);}

结语

刷题不是目的,而是手段。通过这六天的学习,你应该建立起一套完整的算法思维体系:看到题目能快速判断"该用什么模板",写出代码能保证"逻辑正确无 Bug"。

记住几个关键的"成功标志":

  • 能在 5 分钟内默写反转链表代码
  • 能在 10 分钟内写出两数之和的哈希解法
  • 能在 15 分钟内完成二叉树的层序遍历
  • 能独立分析出一道 DP 题的状态转移方程

当这些都做到时,你已经具备了应对大多数面试的能力。接下来的路还很长,但你已经迈出了最关键的一步。

算法之路,道阻且长,行则将至。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询