Skip to content

编程题面试:套路与反套路

作为面试者,我刷了 200 道题;作为面试官,我看了 500 份 code。

编程题不是玄学,有套路可循。但死记硬背也不够,你得真正理解问题的本质。

面试时的心态

面试官出一道 hard 题,通常不是想看你 ac,他是想通过这道题看你怎么想。

标准流程:

  1. clarify:确认题意、数据范围、边界条件
  2. 说思路:先说解法,再说复杂度
  3. 写代码:边写边解释
  4. review:检查 bug

每一步都可能被考察。

三大高频题型

1. 双指针(简单到中等)

两数之和、反转链表、滑动窗口...这类问题用双指针能秒杀。

两数之和(有序数组):

java
public int[] twoSum(int[] numbers, int target) {
    int left = 0, right = numbers.length - 1;
    while (left < right) {
        int sum = numbers[left] + numbers[right];
        if (sum == target) {
            return new int[]{left + 1, right + 1}; // 题目要求下标从 1 开始
        } else if (sum < target) {
            left++;
        } else {
            right--;
        }
    }
    return new int[]{-1, -1};
}

反转链表(迭代):

java
public ListNode reverseList(ListNode head) {
    ListNode prev = null;
    ListNode curr = head;
    while (curr != null) {
        ListNode next = curr.next; // 先保存
        curr.next = prev;           // 反转
        prev = curr;                // 移动 prev
        curr = next;               // 移动 curr
    }
    return prev;
}

合并两个有序数组

java
public void merge(int[] nums1, int m, int[] nums2, int n) {
    int i = m - 1;      // nums1 的有效数据末尾
    int j = n - 1;      // nums2 末尾
    int k = m + n - 1;  // 写入位置

    while (i >= 0 && j >= 0) {
        if (nums1[i] > nums2[j]) {
            nums1[k--] = nums1[i--];
        } else {
            nums1[k--] = nums2[j--];
        }
    }

    // nums2 还剩的话复制过去
    while (j >= 0) {
        nums1[k--] = nums2[j--];
    }
}

2. 哈希表(查询利器)

适用场景:需要 O(1) 查找、两数之和、字符统计。

两数之和(无序数组):

java
public int[] twoSum(int[] nums, int target) {
    Map&lt;Integer, Integer&gt; map = new HashMap&lt;&gt;(); // 值 → 下标
    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[]{-1, -1};
}

3. 递归与 DFS(树的遍历)

树的题想清楚:当前节点做什么,左右子树返回什么。

二叉树最大深度

java
public int maxDepth(TreeNode root) {
    if (root == null) return 0;
    int left = maxDepth(root.left);
    int right = maxDepth(root.right);
    return Math.max(left, right) + 1;
}

刷题顺序建议

阶段题目数目标
入门30双指针、哈希表、简单递归
进阶50DFS/BFS、二分查找、单调栈
熟练80动态规划、回溯、贪心
冲刺40高级数据结构、图论

总结

面试题的核心是:明确问题 → 找规律 → 写代码 → 优化

刷题不是为了背答案,而是训练把未知问题转化为已知套路的能力。

基于 VitePress 构建