编程题面试:套路与反套路
作为面试者,我刷了 200 道题;作为面试官,我看了 500 份 code。
编程题不是玄学,有套路可循。但死记硬背也不够,你得真正理解问题的本质。
面试时的心态
面试官出一道 hard 题,通常不是想看你 ac,他是想通过这道题看你怎么想。
标准流程:
- clarify:确认题意、数据范围、边界条件
- 说思路:先说解法,再说复杂度
- 写代码:边写边解释
- 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<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[]{-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 | 双指针、哈希表、简单递归 |
| 进阶 | 50 | DFS/BFS、二分查找、单调栈 |
| 熟练 | 80 | 动态规划、回溯、贪心 |
| 冲刺 | 40 | 高级数据结构、图论 |
总结
面试题的核心是:明确问题 → 找规律 → 写代码 → 优化。
刷题不是为了背答案,而是训练把未知问题转化为已知套路的能力。
