1. 链表常考操作?反转链表为什么是"基本功"?

链表考察点集中在:指针操作 + 边界条件。高频题:反转、找环(快慢指针)、找中点、合并、删除倒数第 N 个。写链表代码的铁律:

反转链表(迭代版,必背)
public ListNode reverseList(ListNode head) {
    ListNode prev = null, cur = head;
    while (cur != null) {
        ListNode next = cur.next;   // 1. 暂存后继
        cur.next = prev;            // 2. 指向前驱
        prev = cur;                 // 3. prev 前移
        cur = next;                 // 4. cur 前移
    }
    return prev;                   // 新头 = 原尾
}

🎯 面试要点

  • 判断环形链表:快慢指针(slow 走 1 步、fast 走 2 步,相遇则有环);找环入口:相遇后一个从头走,再次相遇即入口
  • 找中点/倒数第 k 个:快慢指针(fast 先走 k 步)
  • 递归版反转也常考:base case 是 head==null || head.next==null

2. 栈、队列、优先队列(堆)的核心用法?

用两个栈实现队列(经典题)
class MyQueue {
    private final Deque<Integer> in  = new ArrayDeque<>();
    private final Deque<Integer> out = new ArrayDeque<>();

    public void push(int x) { in.push(x); }   // 入队只进 in

    private void transfer() {                 // in 倒进 out(一次性)
        if (out.isEmpty())
            while (!in.isEmpty()) out.push(in.pop());
    }

    public int pop() { transfer(); return out.pop(); }   // 出队只从 out
    public int peek() { transfer(); return out.peek(); }
}

🎯 面试要点

  • 均摊 O(1):每个元素最多"进 in 一次、倒一次、出 out 一次"
  • Java 中 Deque 用 ArrayDeque(比 Stack 类快,Stack 是同步的);LinkedList 也是 Deque
  • 优先队列:PriorityQueue 默认小顶堆;大顶堆用 Comparator.reverseOrder()

3. 哈希表的使用场景与手写要点?

两数之和(一题两解)
// 暴力 O(n²):双重循环——面试先说这个再优化

// 哈希 O(n):一次遍历,找 target - nums[i]
public int[] twoSum(int[] nums, int target) {
    Map<Integer, Integer> map = new HashMap<>();
    for (int i = 0; i < nums.length; i++) {
        int need = target - nums[i];
        if (map.containsKey(need))
            return new int[]{map.get(need), i};
        map.put(nums[i], i);      // 边查边存,避免重复使用同一元素
    }
    return new int[]{};
}

🎯 面试要点

  • 哈希的变体:数组下标当哈希(值范围小如 26 个字母 → int[26] 替代 map,更快)
  • 排序后双指针也是两数之和的经典解(有序数组)
  • LinkedHashMap/哈希+链表 = LRU 的结构基础

4. 二叉树遍历与常见题型?

最大深度 & 层序输出
// 最大深度:递归,1 行
public int maxDepth(TreeNode root) {
    return root == null ? 0 : Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}

// 层序遍历(BFS):每层一组
public List<List<Integer>> levelOrder(TreeNode root) {
    List<List<Integer>> res = new ArrayList<>();
    if (root == null) return res;
    Queue<TreeNode> q = new LinkedList<>();
    q.offer(root);
    while (!q.isEmpty()) {
        int size = q.size();              // 关键:先记录本层节点数
        List<Integer> level = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            TreeNode node = q.poll();
            level.add(node.val);
            if (node.left != null) q.offer(node.left);
            if (node.right != null) q.offer(node.right);
        }
        res.add(level);
    }
    return res;
}

🎯 面试要点

  • 树题 90% 是递归;递归三要素:终止条件、子问题、返回值
  • BST 中序遍历 = 有序序列(第 k 小就用中序)
  • 最近公共祖先(LCA):递归判断左右子树是否含 p/q

5. 图的 DFS / BFS 模板与经典题?

图题面试考得少但高频出现:岛屿数量、课程表(拓扑排序)、腐烂橘子(多源 BFS)、克隆图。核心:visited 数组防重复访问。

岛屿数量(DFS 沉岛法,必背)
public int numIslands(char[][] grid) {
    int count = 0;
    for (int i = 0; i < grid.length; i++)
        for (int j = 0; j < grid[0].length; j++)
            if (grid[i][j] == '1') {        // 发现新岛
                count++;
                dfs(grid, i, j);            // 沉掉整座岛
            }
    return count;
}

private void dfs(char[][] g, int i, int j) {
    if (i < 0 || j < 0 || i >= g.length || j >= g[0].length || g[i][j] != '1') return;
    g[i][j] = '0';                          // 原地标记 = visited
    dfs(g, i+1, j); dfs(g, i-1, j);
    dfs(g, i, j+1); dfs(g, i, j-1);
}

🎯 面试要点

  • "沉岛"技巧:访问过的格子改值,省 visited 数组
  • 拓扑排序(课程表):入度表 + BFS 队列,能弹出 n 个节点则无环
  • 多源 BFS(腐烂橘子):先把所有"源"入队,再逐层扩散

🎤 常见面试追问

  1. HashMap 为什么查找快?——key 算哈希直接定位"桶"(数组下标),O(1);冲突时桶内链表/红黑树兜底。
  2. 反转链表:迭代和递归各写一遍?——迭代:三指针(prev/cur/next)逐个反转;递归:先反转后面,再把当前节点接尾。
  3. 怎么判断链表有环?环入口在哪?——快慢指针:快 2 步慢 1 步,相遇则有环;相遇后慢指针从头再走,再次相遇点即环入口。
  4. 二叉树题为什么都用递归?——树天然是递归结构(子树还是树),递归三要素:终止条件、子问题、返回值。
  5. BFS 和 DFS 各自用什么数据结构?——BFS 用队列(一层层扩散,找最短路径);DFS 用栈/递归(一条路走到底)。

📖 名词解释(本页术语)

术语 大白话解释
链表一串节点,每个节点存数据 + 指向下一个的指针。插入删除快(改指针),按下标找慢(要一个个走)。
栈(Stack)后进先出的容器,像叠盘子:只能从顶上放和拿。用于括号匹配、撤销、DFS。
队列(Queue)先进先出的容器,像排队:先来的先处理。用于 BFS、任务排队。
哈希表按"键"直接算出存储位置的表,查找 O(1)。Java 的 HashMap 就是它。
二叉树每个节点最多两个孩子的树结构。前/中/后序遍历是基本功。
二叉搜索树(BST)左子 < 根 < 右子的二叉树,查找 O(log n);中序遍历输出有序序列。
红黑树自平衡的 BST:插入删除后自动调整保持平衡,保证最坏 O(log n)。TreeMap、HashMap 桶(超 8 个)用它。
优先队列(堆)每次都能取出最大/最小值的容器(O(log n)),Java 的 PriorityQueue。
图(Graph)节点 + 节点间的边。用于社交关系、地图、依赖关系。BFS/DFS 是遍历它的两种方式。
BFS / DFS广度优先(一层层扩散,找最短路径)/ 深度优先(一条路走到底再回头)——图与树的两大遍历法。
⚠️ 本页面由 AI 生成,内容仅供参考,请以官方文档和实际源码为准。