Interview AiBox logo

Interview AiBox 实时 AI 助手,让你自信应答每一场面试

立即体验 Interview AiBoxarrow_forward
6 分钟阅读Interview AiBox Team

Top 20 LeetCode高频面试题详解(附代码与思路)

精选20道最高频LeetCode面试题,每题包含题目描述、核心思路、Python/Java代码实现和复杂度分析,助你理解解题模式而非死记硬背。

  • sellLeetcode
  • sellInterview questions
  • sellAlgorithm
  • sellData structure
  • sellCoding

Top 20 LeetCode高频面试题详解(附代码与思路)

刷题无数,面试还是挂?问题可能不在数量,而在方法。

很多候选人刷了300+道题,面试时遇到新题还是懵。为什么?因为他们记住了答案,而不是理解了模式

这篇文章精选20道最高频LeetCode题目,不只是给你答案,而是帮你建立解题思维框架。掌握了这些模式,你就能举一反三,应对任何变体。


为什么是这20道题?

我们分析了Google、Meta、Amazon、Apple、Microsoft等大厂近两年的面试数据,这20道题:

  • 出现频率最高:覆盖80%+的面试场景
  • 代表性强:每道题代表一类经典问题
  • 难度适中:Medium为主,Hard为辅,符合真实面试难度

更重要的是,这20道题覆盖了10大核心解题模式

  1. 双指针
  2. 滑动窗口
  3. 哈希表
  4. 深度优先搜索
  5. 广度优先搜索
  6. 二分查找
  7. 动态规划
  8. 回溯
  9. 堆/优先队列
  10. 设计类

Two Sum(两数之和)

难度:Easy
出现频率:⭐⭐⭐⭐⭐
核心模式:哈希表

题目描述

给定一个整数数组 nums 和一个目标值 target,在数组中找出和为目标值的两个数,返回它们的索引。

示例:

输入:nums = [2, 7, 11, 15], target = 9
输出:[0, 1]
解释:nums[0] + nums[1] = 2 + 7 = 9

核心思路

暴力解法是O(n²),但我们可以用哈希表优化到O(n)。

关键洞察:对于每个数num,我们只需要知道target - num是否在数组中。

算法流程

  1. 遍历数组,对于每个元素nums[i]
  2. 计算complement = target - nums[i]
  3. 检查complement是否在哈希表中
  4. 如果在,返回结果;如果不在,将nums[i]加入哈希表

代码实现

Python:

def twoSum(nums: List[int], target: int) -> List[int]:
    seen = {}
    for i, num in enumerate(nums):
        complement = target - num
        if complement in seen:
            return [seen[complement], i]
        seen[num] = i
    return []

Java:

public int[] twoSum(int[] nums, int target) {
    Map<Integer, Integer> seen = new HashMap<>();
    for (int i = 0; i < nums.length; i++) {
        int complement = target - nums[i];
        if (seen.containsKey(complement)) {
            return new int[]{seen.get(complement), i};
        }
        seen.put(nums[i], i);
    }
    return new int[]{};
}

复杂度分析

  • 时间复杂度:O(n),只需遍历一次数组
  • 空间复杂度:O(n),哈希表最多存储n个元素

变体题目

  • Three Sum(三数之和)
  • Four Sum(四数之和)
  • Two Sum II - Input Array Is Sorted(有序数组的两数之和)

LRU Cache(LRU缓存)

难度:Medium
出现频率:⭐⭐⭐⭐⭐
核心模式:设计类 + 双向链表 + 哈希表

题目描述

设计一个LRU(最近最少使用)缓存,支持getput操作,要求O(1)时间复杂度。

示例:

LRUCache lRUCache = new LRUCache(2);
lRUCache.put(1, 1); // 缓存是 {1=1}
lRUCache.put(2, 2); // 缓存是 {1=1, 2=2}
lRUCache.get(1);    // 返回 1,缓存变为 {2=2, 1=1}
lRUCache.put(3, 3); // 淘汰 key 2,缓存是 {1=1, 3=3}
lRUCache.get(2);    // 返回 -1(未找到)

核心思路

LRU的核心是"最近使用"的顺序管理。我们需要:

  1. 快速查找:哈希表
  2. 快速调整顺序:双向链表

数据结构组合

  • HashMap<Integer, Node>:key到节点的映射,O(1)查找
  • DoublyLinkedList:维护使用顺序,头部是最近使用的,尾部是最久未使用的

代码实现

Python:

class Node:
    def __init__(self, key=0, val=0):
        self.key = key
        self.val = val
        self.prev = None
        self.next = None

class LRUCache:
    def __init__(self, capacity: int):
        self.capacity = capacity
        self.cache = {}
        self.head = Node()
        self.tail = Node()
        self.head.next = self.tail
        self.tail.prev = self.head
    
    def _remove(self, node):
        node.prev.next = node.next
        node.next.prev = node.prev
    
    def _add_to_front(self, node):
        node.next = self.head.next
        node.prev = self.head
        self.head.next.prev = node
        self.head.next = node
    
    def get(self, key: int) -> int:
        if key not in self.cache:
            return -1
        node = self.cache[key]
        self._remove(node)
        self._add_to_front(node)
        return node.val
    
    def put(self, key: int, value: int) -> None:
        if key in self.cache:
            node = self.cache[key]
            node.val = value
            self._remove(node)
            self._add_to_front(node)
        else:
            if len(self.cache) >= self.capacity:
                lru = self.tail.prev
                self._remove(lru)
                del self.cache[lru.key]
            node = Node(key, value)
            self.cache[key] = node
            self._add_to_front(node)

Java:

class LRUCache {
    class Node {
        int key, val;
        Node prev, next;
        Node(int key, int val) {
            this.key = key;
            this.val = val;
        }
    }
    
    private Map<Integer, Node> cache;
    private Node head, tail;
    private int capacity;
    
    public LRUCache(int capacity) {
        this.capacity = capacity;
        cache = new HashMap<>();
        head = new Node(0, 0);
        tail = new Node(0, 0);
        head.next = tail;
        tail.prev = head;
    }
    
    private void remove(Node node) {
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }
    
    private void addToFront(Node node) {
        node.next = head.next;
        node.prev = head;
        head.next.prev = node;
        head.next = node;
    }
    
    public int get(int key) {
        if (!cache.containsKey(key)) return -1;
        Node node = cache.get(key);
        remove(node);
        addToFront(node);
        return node.val;
    }
    
    public void put(int key, int value) {
        if (cache.containsKey(key)) {
            Node node = cache.get(key);
            node.val = value;
            remove(node);
            addToFront(node);
        } else {
            if (cache.size() >= capacity) {
                Node lru = tail.prev;
                remove(lru);
                cache.remove(lru.key);
            }
            Node node = new Node(key, value);
            cache.put(key, node);
            addToFront(node);
        }
    }
}

复杂度分析

  • 时间复杂度:get和put都是O(1)
  • 空间复杂度:O(capacity)

面试要点

  • 为什么用双向链表而不是单向链表?
  • 如何处理边界条件(容量为0、空缓存等)?
  • 能否用Java的LinkedHashMap简化实现?

Number of Islands(岛屿数量)

难度:Medium
出现频率:⭐⭐⭐⭐⭐
核心模式:DFS/BFS + 网格图

题目描述

给定一个由'1'(陆地)和'0'(水)组成的二维网格,计算岛屿的数量。岛屿被水包围,由相邻的陆地连接而成(水平或垂直方向)。

示例:

输入:
11110
11010
11000
00000
输出:1

核心思路

这是一道经典的连通分量计数问题。

算法流程

  1. 遍历网格的每个位置
  2. 遇到'1'时,岛屿数量+1,然后用DFS/BFS将整个岛屿标记为已访问(改为'0')
  3. 继续遍历,直到所有位置都被访问

代码实现

Python(DFS):

def numIslands(grid: List[List[str]]) -> int:
    if not grid:
        return 0
    
    rows, cols = len(grid), len(grid[0])
    count = 0
    
    def dfs(r, c):
        if r < 0 or r >= rows or c < 0 or c >= cols or grid[r][c] == '0':
            return
        grid[r][c] = '0'
        dfs(r+1, c)
        dfs(r-1, c)
        dfs(r, c+1)
        dfs(r, c-1)
    
    for r in range(rows):
        for c in range(cols):
            if grid[r][c] == '1':
                count += 1
                dfs(r, c)
    
    return count

Java(BFS):

public int numIslands(char[][] grid) {
    if (grid == null || grid.length == 0) return 0;
    
    int rows = grid.length, cols = grid[0].length;
    int count = 0;
    
    for (int r = 0; r < rows; r++) {
        for (int c = 0; c < cols; c++) {
            if (grid[r][c] == '1') {
                count++;
                bfs(grid, r, c);
            }
        }
    }
    return count;
}

private void bfs(char[][] grid, int r, int c) {
    int rows = grid.length, cols = grid[0].length;
    Queue<int[]> queue = new LinkedList<>();
    queue.offer(new int[]{r, c});
    grid[r][c] = '0';
    
    int[][] dirs = {{1,0}, {-1,0}, {0,1}, {0,-1}};
    while (!queue.isEmpty()) {
        int[] cell = queue.poll();
        for (int[] dir : dirs) {
            int nr = cell[0] + dir[0];
            int nc = cell[1] + dir[1];
            if (nr >= 0 && nr < rows && nc >= 0 && nc < cols && grid[nr][nc] == '1') {
                queue.offer(new int[]{nr, nc});
                grid[nr][nc] = '0';
            }
        }
    }
}

复杂度分析

  • 时间复杂度:O(m×n),每个格子最多访问一次
  • 空间复杂度:O(m×n),DFS递归栈或BFS队列的最坏情况

变体题目

  • Max Area of Island(岛屿的最大面积)
  • Surrounded Regions(被包围的区域)
  • Number of Distinct Islands(不同岛屿的数量)

Merge Two Sorted Lists(合并两个有序链表)

难度:Easy
出现频率:⭐⭐⭐⭐⭐
核心模式:双指针 + 链表

题目描述

将两个升序链表合并为一个新的升序链表并返回。

示例:

输入:l1 = 1->2->4, l2 = 1->3->4
输出:1->1->2->3->4->4

核心思路

使用双指针分别遍历两个链表,每次选择较小的节点加入结果链表。

技巧:使用虚拟头节点(dummy node)简化边界处理。

代码实现

Python(迭代):

def mergeTwoLists(l1: ListNode, l2: ListNode) -> ListNode:
    dummy = ListNode(0)
    curr = dummy
    
    while l1 and l2:
        if l1.val <= l2.val:
            curr.next = l1
            l1 = l1.next
        else:
            curr.next = l2
            l2 = l2.next
        curr = curr.next
    
    curr.next = l1 if l1 else l2
    return dummy.next

Java(递归):

public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
    if (l1 == null) return l2;
    if (l2 == null) return l1;
    
    if (l1.val <= l2.val) {
        l1.next = mergeTwoLists(l1.next, l2);
        return l1;
    } else {
        l2.next = mergeTwoLists(l1, l2.next);
        return l2;
    }
}

复杂度分析

  • 时间复杂度:O(n+m),n和m是两个链表的长度
  • 空间复杂度:迭代O(1),递归O(n+m)(栈空间)

Valid Parentheses(有效的括号)

难度:Easy
出现频率:⭐⭐⭐⭐⭐
核心模式:栈

题目描述

给定一个只包含括号的字符串,判断括号是否有效。

示例:

输入:"()[]{}"
输出:true

输入:"([)]"
输出:false

核心思路

使用栈来匹配括号:

  1. 遇到左括号,入栈
  2. 遇到右括号,检查栈顶是否匹配
  3. 最后栈应该为空

代码实现

Python:

def isValid(s: str) -> bool:
    stack = []
    mapping = {')': '(', ']': '[', '}': '{'}
    
    for char in s:
        if char in mapping:
            if not stack or stack[-1] != mapping[char]:
                return False
            stack.pop()
        else:
            stack.append(char)
    
    return not stack

Java:

public boolean isValid(String s) {
    Deque<Character> stack = new ArrayDeque<>();
    Map<Character, Character> map = Map.of(')', '(', ']', '[', '}', '{');
    
    for (char c : s.toCharArray()) {
        if (map.containsKey(c)) {
            if (stack.isEmpty() || stack.pop() != map.get(c)) {
                return false;
            }
        } else {
            stack.push(c);
        }
    }
    return stack.isEmpty();
}

复杂度分析

  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

Maximum Subarray(最大子数组和)

难度:Medium
出现频率:⭐⭐⭐⭐⭐
核心模式:动态规划 / Kadane算法

题目描述

找到具有最大和的连续子数组,返回其和。

示例:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6

核心思路

Kadane算法:对于每个位置,选择"以当前元素结尾的最大和"。

状态转移

dp[i] = max(nums[i], dp[i-1] + nums[i])

代码实现

Python:

def maxSubArray(nums: List[int]) -> int:
    max_sum = curr_sum = nums[0]
    
    for num in nums[1:]:
        curr_sum = max(num, curr_sum + num)
        max_sum = max(max_sum, curr_sum)
    
    return max_sum

Java:

public int maxSubArray(int[] nums) {
    int maxSum = nums[0], currSum = nums[0];
    
    for (int i = 1; i < nums.length; i++) {
        currSum = Math.max(nums[i], currSum + nums[i]);
        maxSum = Math.max(maxSum, currSum);
    }
    return maxSum;
}

复杂度分析

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

Binary Tree Level Order Traversal(二叉树层序遍历)

难度:Medium
出现频率:⭐⭐⭐⭐⭐
核心模式:BFS

题目描述

给定二叉树,返回其节点值的层序遍历

Interview AiBox logo

Interview AiBox — 面试搭档

不只是准备,更是实时陪练

Interview AiBox 在面试过程中提供实时屏幕提示、AI 模拟面试和智能复盘,让你每一次回答都更有信心。

分享文章

复制链接,或一键分享到常用平台

外部分享

继续阅读

article

schedule2026年3月09日

Top 20 LeetCode Questions You Must Know in 2026

A curated list of the 20 most frequently asked LeetCode interview questions with detailed explanations, Python/Java implementations, and complexity analysis. Focus on patterns, not memorization.

Top 20 LeetCode高频面试题详解(附代码与思路) | Interview AiBox