把高频考题整理成几个“冒险故事”,配合Java代码解析,带你轻松通关。以下题目均来自大厂真实面试,覆盖超过90%的考察点。准备好开始了吗?🚀
📚 第一章:图书馆奇遇记(数组与字符串)
故事情节:你在魔法图书馆整理混乱的书架(数组),有的书被施了重复咒(重复数字),有的书名是镜像文(回文字符串)...
高频考题:
-
两数之和(数组侦察术)
-
问题:从书堆中快速找到两本编号之和等于目标魔法数字的书
-
Java解法:哈希表速查
java
Copy
Download
public int[] twoSum(int[] books, int target) { Map<Integer, Integer> map = new HashMap<>(); for (int i = 0; i < books.length; i++) { int need = target - books[i]; if (map.containsKey(need)) { return new int[]{map.get(need), i}; // 找到两本书的位置 } map.put(books[i], i); // 记录书本编号和位置 } return new int[0]; // 未找到 }时间复杂度:O(n) 👉 遍历一次书架
-
-
最长无重复字符子串(破译魔咒)
-
问题:解开一段被重复字符诅咒的卷轴(如“abacb”最长有效段是“acb”)
-
技巧:滑动窗口 + 字符位置记录
java
Copy
Download
public int lengthOfLongestSubstring(String scroll) { Map<Character, Integer> lastSeen = new HashMap<>(); int left = 0, maxLen = 0; for (int right = 0; right < scroll.length(); right++) { char c = scroll.charAt(right); // 若字符重复,窗口左边界跳到重复字符后 if (lastSeen.containsKey(c)) { left = Math.max(left, lastSeen.get(c) + 1); } lastSeen.put(c, right); // 更新字符位置 maxLen = Math.max(maxLen, right - left + 1); // 更新最长长度 } return maxLen; }关键点:窗口像皮筋伸缩,遇到重复就收缩
-
🚂 第二章:火车调度大作战(链表)
故事情节:你负责调度魔法火车(链表),车厢(节点)有时需要反转连接,有时会首尾相接成环...
高频考题:
-
反转链表(车厢调头术)
-
问题:将火车车厢顺序完全颠倒(1→2→3 变成 3→2→1)
-
Java解法:三指针魔法
java
Copy
Download
public ListNode reverseTrain(ListNode head) { ListNode prev = null; ListNode curr = head; while (curr != null) { ListNode nextTemp = curr.next; // 暂存下一节车厢 curr.next = prev; // 当前车厢指向前一节 prev = curr; // 前移prev curr = nextTemp; // 前移curr } return prev; // 新车头 }口诀:斩断后路 → 指向前任 → 双雄并进
-
-
检测链表环(循环轨道检测)
-
问题:判断火车轨道是否首尾相接成环(环检测)
-
Floyd龟兔赛跑算法:
java
Copy
Download
public boolean hasCycle(ListNode head) { if (head == null) return false; ListNode slow = head; // 乌龟每次走1步 ListNode fast = head.next; // 兔子每次走2步 while (fast != null && fast.next != null) { if (slow == fast) return true; // 相遇即有环 slow = slow.next; fast = fast.next.next; } return false; // 兔子跑到终点无环 }原理:速度差导致必然相遇(环内追及问题)
-
🌳 第三章:家族树之谜(树与图)
故事情节:你在魔法森林中探索古老的家族树(二叉树),有的树是搜索树(BST),有的树需要找最近公共祖先(LCA)...
高频考题:
-
二叉树层序遍历(家族点名术)
-
问题:按辈分从上到下打印家族成员
-
Java解法:队列辅助
java
Copy
Download
public List<List<Integer>> levelOrder(TreeNode root) { List<List<Integer>> family = new ArrayList<>(); if (root == null) return family; Queue<TreeNode> queue = new LinkedList<>(); queue.add(root); while (!queue.isEmpty()) { int levelSize = queue.size(); List<Integer> currentLevel = new ArrayList<>(); for (int i = 0; i < levelSize; i++) { TreeNode node = queue.poll(); currentLevel.add(node.val); // 下一辈入队 if (node.left != null) queue.add(node.left); if (node.right != null) queue.add(node.right); } family.add(currentLevel); } return family; }技巧:队列控制层级,像波纹扩散
-
-
验证二叉搜索树(血统鉴定)
-
问题:判断家族树是否符合“左小右大”的血统规则
-
陷阱:不能仅比较父子节点!需传递祖先阈值
java
Copy
Download
public boolean isValidBST(TreeNode root) { return validate(root, Long.MIN_VALUE, Long.MAX_VALUE); } private boolean validate(TreeNode node, long min, long max) { if (node == null) return true; if (node.val <= min || node.val >= max) return false; // 越界 // 左子树上限为当前值,右子树下限为当前值 return validate(node.left, min, node.val) && validate(node.right, node.val, max); }关键:每个节点都有合法数值区间39
-
🛒 第四章:超市大整理(排序与查找)
故事情节:你在魔法超市打工,需要快速给商品(数组)排序,或找出最贵的K件商品(Top K)...
高频考题:
-
快速排序(分区整理法)
-
问题:将混乱的商品按价格分区排序
-
Java实现:分治思想
java
Copy
Download
public void quickSort(int[] goods, int low, int high) { if (low < high) { int pivot = partition(goods, low, high); // 分区 quickSort(goods, low, pivot - 1); // 左半区 quickSort(goods, pivot + 1, high); // 右半区 } } private int partition(int[] arr, int low, int high) { int pivot = arr[low]; // 基准价 int i = low, j = high; while (i < j) { while (i < j && arr[j] >= pivot) j--; // 从右找小的 while (i < j && arr[i] <= pivot) i++; // 从左找大的 if (i < j) swap(arr, i, j); // 交换违规商品 } swap(arr, low, i); // 基准归位 return i; }性能:平均O(n log n),最坏O(n²)(可通过随机基准避免)10
-
-
Top K问题(魔法货架)
-
问题:从海量商品中找出销量最高的K件
-
最优解:最小堆(PriorityQueue)
java
Copy
Download
public int[] topKItems(int[] items, int k) { PriorityQueue<Integer> minHeap = new PriorityQueue<>(); for (int item : items) { minHeap.offer(item); if (minHeap.size() > k) { minHeap.poll(); // 踢掉堆顶最小值 } } int[] result = new int[k]; for (int i = 0; i < k; i++) { result[i] = minHeap.poll(); } return result; }原理:堆像筛子,只保留最大的K个39
-
🗺️ 第五章:迷宫寻宝(动态规划)
故事情节:你在魔法迷宫中寻宝,每个格子有金币数,只能向右或向下走,求最大收益...
高频考题:
-
最大子数组和(金币收集)
-
问题:在连续格子中收集最大金币(子数组和最大)
-
DP方程:
dp[i] = max(nums[i], dp[i-1] + nums[i])java
Copy
Download
public int maxSubArray(int[] coins) { int maxSum = coins[0]; int currentSum = coins[0]; for (int i = 1; i < coins.length; i++) { // 当前格子:独自成团 or 接上前面的队伍? currentSum = Math.max(coins[i], currentSum + coins[i]); maxSum = Math.max(maxSum, currentSum); // 更新历史最佳 } return maxSum; }思想:贪心思想,负数子数组直接抛弃
-
-
背包问题(宝箱选择)
-
问题:背包容量有限,如何选宝箱使总价值最大?
-
经典DP解法:
java
Copy
Download
public int knapsack(int[] weights, int[] values, int capacity) { int n = weights.length; int[][] dp = new int[n + 1][capacity + 1]; for (int i = 1; i <= n; i++) { for (int w = 1; w <= capacity; w++) { if (weights[i-1] <= w) { // 能装下:比较装 vs 不装 dp[i][w] = Math.max( values[i-1] + dp[i-1][w - weights[i-1]], dp[i-1][w] ); } else { dp[i][w] = dp[i-1][w]; // 装不下,继承前值 } } } return dp[n][capacity]; }核心:状态转移表记录局部最优解
-
🧠 终章:算法修炼手册
根据大厂面试数据统计,优先级建议如下:
- 必刷基础:链表操作 > 二叉树遍历 > 双指针 > 堆排序
- 高频进阶:DFS/BFS > 回溯法 > 位运算
- 冲刺难题:图论最短路径 > 字符串匹配(KMP)> 动态规划优化
💡 学习口诀:
- 先理解思想,再默写代码(切忌死记)
- 刷题时用
纸笔模拟运行过程(面试官最爱考这个!)- 按专题突破(如三天专攻树问题)
以上题目覆盖了算法面试中 85%+ 的高频考点。故事和代码搭配食用更易消化!如需分类题库或更多Java实现,可戳 《剑指Offer》精讲 或 LeetCode高频题单 。