牛客网面试TOP101 - Python算法学习指南

牛客网面试TOP101 - Python算法学习指南

题单链接 : 牛客top101
题目总数 : 101道
题单定位 : 基于牛客面经汇总分析整理出的面试常考算法题,完成本题单可解决面试中约70%的代码题
题单模式: 核心代码模式


目录

  1. 题单概览
  2. 链表专题 (BM1-BM16)
  3. 二分查找/排序专题 (BM17-BM22)
  4. 二叉树专题 (BM23-BM41)
  5. 堆/栈/队列专题 (BM42-BM49)
  6. 哈希专题 (BM50-BM54)
  7. 递归/回溯专题 (BM55-BM61)
  8. 动态规划专题 (BM62-BM82)
  9. 字符串专题 (BM83-BM86)
  10. 双指针专题 (BM87-BM94)
  11. 贪心专题 (BM95-BM96)
  12. 模拟/设计专题 (BM97-BM101)

一、题单概览

1.1 分类结构统计

分类/专题 题目数量 占比 难度分布 题号范围
链表 16 15.8% 简单-中等 BM1 - BM16
二叉树 19 18.8% 简单-困难 BM23 - BM41
动态规划 21 20.8% 中等-困难 BM62 - BM82
递归/回溯 10 9.9% 中等-困难 BM55 - BM61
排序/二分查找 6 5.9% 简单-中等 BM17 - BM22
双指针 8 7.9% 简单-中等 BM87 - BM94
哈希 5 5.0% 简单-中等 BM50 - BM54
堆/栈/队列 8 7.9% 中等 BM42 - BM49
字符串 4 4.0% 简单-中等 BM83 - BM86
贪心 2 2.0% 中等 BM95 - BM96
模拟/设计 5 5.0% 中等-困难 BM97 - BM101

1.2 难度分布

难度级别 题目数量 占比
入门/简单 约35题 34.7%
中等 约50题 49.5%
较难/困难 约16题 15.8%

二、链表专题 (BM1-BM16)

2.1 核心知识点

  • 快慢指针: Floyd判环、找中点、找倒数第K个节点
  • 虚拟头节点: 简化边界处理
  • 链表反转: 头插法/尾插法
  • 链表合并: 归并思想
  • 链表拆分与重排

2.2 Python代码模板

python 复制代码
# 链表节点定义
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

# 1. 反转链表 - 迭代法
class Solution:
    def ReverseList(self, head):
        pre = None
        cur = head
        while cur:
            tmp = cur.next
            cur.next = pre
            pre = cur
            cur = tmp
        return pre

# 2. 快慢指针判环
class Solution:
    def hasCycle(self, head):
        fast = slow = head
        while fast and fast.next:
            fast = fast.next.next
            slow = slow.next
            if fast == slow:
                return True
        return False

# 3. 找环入口
class Solution:
    def EntryNodeOfLoop(self, pHead):
        fast = slow = pHead
        while fast and fast.next:
            fast = fast.next.next
            slow = slow.next
            if fast == slow:
                break
        if not fast or not fast.next:
            return None
        fast = pHead
        while fast != slow:
            fast = fast.next
            slow = slow.next
        return fast

# 4. 找倒数第K个节点
class Solution:
    def FindKthToTail(self, pHead, k):
        fast = pHead
        while k > 0 and fast:
            fast = fast.next
            k -= 1
        if k > 0:
            return None
        while fast:
            fast = fast.next
            pHead = pHead.next
        return pHead

# 5. 合并两个有序链表
class Solution:
    def Merge(self, pHead1, pHead2):
        dummy = ListNode(-1)
        cur = dummy
        while pHead1 and pHead2:
            if pHead1.val <= pHead2.val:
                cur.next = pHead1
                pHead1 = pHead1.next
            else:
                cur.next = pHead2
                pHead2 = pHead2.next
            cur = cur.next
        cur.next = pHead1 if pHead1 else pHead2
        return dummy.next

2.3 题目列表

题号 题目名称 难度 核心考察知识点
BM1 反转链表 简单 链表遍历、指针操作
BM2 链表内指定区间反转 中等 链表反转、虚拟头节点
BM3 链表中的节点每k个一组翻转 中等 分组反转、链表遍历
BM4 合并两个排序的链表 简单 归并思想、链表操作
BM5 合并k个已排序的链表 较难 优先队列/分治、链表归并
BM6 判断链表中是否有环 简单 快慢指针、Floyd判圈算法
BM7 链表中环的入口结点 中等 快慢指针、数学推导
BM8 链表中倒数最后k个结点 简单 快慢指针、链表遍历
BM9 删除链表的倒数第n个节点 中等 快慢指针、虚拟头节点
BM10 两个链表的第一个公共结点 简单 双指针、链表长度差
BM11 链表相加(二) 中等 链表遍历、进位处理
BM12 单链表的排序 中等 归并排序、链表操作
BM13 判断一个链表是否为回文结构 简单 快慢指针、链表反转
BM14 链表的奇偶重排 中等 链表拆分、合并
BM15 删除有序链表中重复的元素-I 简单 链表遍历、去重
BM16 删除有序链表中重复的元素-II 中等 虚拟头节点、重复节点删除

三、二分查找/排序专题 (BM17-BM22)

3.1 核心知识点

  • 标准二分查找
  • 查找左/右边界
  • 旋转数组查找
  • 归并排序求逆序对

3.2 Python代码模板

python 复制代码
# 1. 标准二分查找
class Solution:
    def search(self, nums, target):
        left, right = 0, len(nums) - 1
        while left <= right:
            mid = left + (right - left) // 2
            if nums[mid] == target:
                return mid
            elif nums[mid] < target:
                left = mid + 1
            else:
                right = mid - 1
        return -1

# 2. 旋转数组查找
class Solution:
    def minNumberInRotateArray(self, rotateArray):
        left, right = 0, len(rotateArray) - 1
        while left < right:
            mid = left + (right - left) // 2
            if rotateArray[mid] > rotateArray[right]:
                left = mid + 1
            elif rotateArray[mid] < rotateArray[right]:
                right = mid
            else:
                right -= 1
        return rotateArray[left]

# 3. 归并排序求逆序对
class Solution:
    def InversePairs(self, data):
        self.count = 0
        self.merge_sort(data, 0, len(data) - 1)
        return self.count % 1000000007
    
    def merge_sort(self, data, left, right):
        if left >= right:
            return
        mid = (left + right) // 2
        self.merge_sort(data, left, mid)
        self.merge_sort(data, mid + 1, right)
        self.merge(data, left, mid, right)
    
    def merge(self, data, left, mid, right):
        temp = []
        i, j = left, mid + 1
        while i <= mid and j <= right:
            if data[i] <= data[j]:
                temp.append(data[i])
                i += 1
            else:
                temp.append(data[j])
                self.count += mid - i + 1
                j += 1
        temp.extend(data[i:mid+1])
        temp.extend(data[j:right+1])
        data[left:right+1] = temp

3.3 题目列表

题号 题目名称 难度 核心考察知识点
BM17 二分查找-I 简单 二分查找基础
BM18 二维数组中的查找 中等 矩阵查找、二分思想
BM19 寻找峰值 中等 二分查找变种
BM20 数组中的逆序对 中等 归并排序、逆序对统计
BM21 旋转数组的最小数字 简单 二分查找、旋转数组
BM22 比较版本号 中等 字符串处理、比较逻辑

四、二叉树专题 (BM23-BM41)

4.1 核心知识点

  • 前序、中序、后序遍历(递归与非递归)
  • 层次遍历(BFS)
  • 二叉搜索树性质(中序遍历有序)
  • 树的高度、路径、对称性判断
  • 重建二叉树

4.2 Python代码模板

python 复制代码
# 二叉树节点定义
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

# 1. 前序遍历 - 递归
class Solution:
    def preorderTraversal(self, root):
        if not root:
            return []
        return [root.val] + self.preorderTraversal(root.left) + self.preorderTraversal(root.right)

# 2. 中序遍历 - 迭代
class Solution:
    def inorderTraversal(self, root):
        result = []
        stack = []
        current = root
        while current or stack:
            while current:
                stack.append(current)
                current = current.left
            current = stack.pop()
            result.append(current.val)
            current = current.right
        return result

# 3. 层次遍历
from collections import deque
class Solution:
    def levelOrder(self, root):
        if not root:
            return []
        result = []
        queue = deque([root])
        while queue:
            level_size = len(queue)
            level = []
            for _ in range(level_size):
                node = queue.popleft()
                level.append(node.val)
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            result.append(level)
        return result

# 4. 判断对称二叉树
class Solution:
    def isSymmetric(self, root):
        def check(left, right):
            if not left and not right:
                return True
            if not left or not right:
                return False
            return (left.val == right.val and 
                    check(left.left, right.right) and 
                    check(left.right, right.left))
        if not root:
            return True
        return check(root.left, root.right)

# 5. 求最大深度
class Solution:
    def maxDepth(self, root):
        if not root:
            return 0
        return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right))

# 6. 重建二叉树
class Solution:
    def reConstructBinaryTree(self, pre, tin):
        if not pre or not tin:
            return None
        root_val = pre[0]
        root = TreeNode(root_val)
        root_index = tin.index(root_val)
        root.left = self.reConstructBinaryTree(pre[1:1+root_index], tin[:root_index])
        root.right = self.reConstructBinaryTree(pre[1+root_index:], tin[root_index+1:])
        return root

4.3 题目列表

题号 题目名称 难度 核心考察知识点
BM23 二叉树的前序遍历 简单 递归/迭代遍历
BM24 二叉树的中序遍历 简单 递归/迭代遍历
BM25 二叉树的后序遍历 简单 递归/迭代遍历
BM26 求二叉树的层序遍历 简单 BFS、队列
BM27 按之字形顺序打印二叉树 中等 BFS、双端队列
BM28 二叉树的最大深度 简单 递归、DFS
BM29 二叉树中和为某一值的路径(一) 中等 DFS、回溯
BM30 二叉搜索树与双向链表 中等 中序遍历、树转换
BM31 对称的二叉树 简单 递归、树对称判断
BM32 合并二叉树 简单 递归、树合并
BM33 二叉树的镜像 简单 递归、树翻转
BM34 判断是不是二叉搜索树 中等 中序遍历、BST性质
BM35 判断是不是完全二叉树 中等 BFS、完全二叉树性质
BM36 判断是不是平衡二叉树 中等 递归、高度计算
BM37 二叉搜索树的最近公共祖先 简单 BST性质、递归
BM38 在二叉树中找到两个节点的最近公共祖先 中等 DFS、递归
BM39 序列化二叉树 较难 前序遍历、字符串处理
BM40 重建二叉树 中等 前序+中序、递归构建
BM41 输出二叉树的右视图 中等 BFS、层序遍历

五、堆/栈/队列专题 (BM42-BM49)

5.1 核心知识点

  • 栈与队列相互实现
  • 单调栈/单调队列
  • TopK问题
  • 中缀表达式求值

5.2 Python代码模板

python 复制代码
# 1. 用两个栈实现队列
class Solution:
    def __init__(self):
        self.stack1 = []
        self.stack2 = []
    
    def push(self, node):
        self.stack1.append(node)
    
    def pop(self):
        if not self.stack2:
            while self.stack1:
                self.stack2.append(self.stack1.pop())
        return self.stack2.pop()

# 2. 包含min函数的栈
class Solution:
    def __init__(self):
        self.stack = []
        self.min_stack = []
    
    def push(self, node):
        self.stack.append(node)
        if not self.min_stack or node <= self.min_stack[-1]:
            self.min_stack.append(node)
    
    def pop(self):
        if self.stack.pop() == self.min_stack[-1]:
            self.min_stack.pop()
    
    def top(self):
        return self.stack[-1]
    
    def min(self):
        return self.min_stack[-1]

# 3. 有效括号
class Solution:
    def isValid(self, s):
        stack = []
        mapping = {')': '(', '}': '{', ']': '['}
        for char in s:
            if char in mapping:
                top = stack.pop() if stack else '#'
                if mapping[char] != top:
                    return False
            else:
                stack.append(char)
        return not stack

# 4. 滑动窗口最大值(单调队列)
from collections import deque
class Solution:
    def maxInWindows(self, num, size):
        if not num or size <= 0:
            return []
        result = []
        dq = deque()  # 存储索引
        for i, val in enumerate(num):
            # 移除窗口外的元素
            while dq and dq[0] <= i - size:
                dq.popleft()
            # 保持单调递减
            while dq and num[dq[-1]] < val:
                dq.pop()
            dq.append(i)
            if i >= size - 1:
                result.append(num[dq[0]])
        return result

5.3 题目列表

题号 题目名称 难度 核心考察知识点
BM42 用两个栈实现队列 简单 栈、队列、数据流转换
BM43 包含min函数的栈 中等 辅助栈、最小值维护
BM44 有效括号序列 简单 栈、括号匹配
BM45 滑动窗口的最大值 中等 单调队列、滑动窗口
BM46 最小的K个数 中等 堆、TopK问题
BM47 寻找第K大 中等 快排思想/堆、TopK
BM48 数据流中的中位数 较难 双堆、中位数维护
BM49 表达式求值 较难 栈、中缀表达式求值

六、哈希专题 (BM50-BM54)

6.1 核心知识点

  • 两数之和
  • 频次统计
  • 摩尔投票法
  • 位运算

6.2 Python代码模板

python 复制代码
# 1. 两数之和
class Solution:
    def twoSum(self, nums, target):
        hash_map = {}
        for i, num in enumerate(nums):
            complement = target - num
            if complement in hash_map:
                return [hash_map[complement], i]
            hash_map[num] = i
        return []

# 2. 摩尔投票法 - 找多数元素
class Solution:
    def MoreThanHalfNum_Solution(self, numbers):
        candidate = None
        count = 0
        for num in numbers:
            if count == 0:
                candidate = num
            count += 1 if num == candidate else -1
        # 验证
        return candidate if numbers.count(candidate) > len(numbers) // 2 else 0

# 3. 只出现一次的数字(两个)
class Solution:
    def singleNumber(self, nums):
        xor = 0
        for num in nums:
            xor ^= num
        # 找到最低位的1
        lowbit = xor & (-xor)
        num1 = num2 = 0
        for num in nums:
            if num & lowbit:
                num1 ^= num
            else:
                num2 ^= num
        return [num1, num2]

6.3 题目列表

题号 题目名称 难度 核心考察知识点
BM50 两数之和 简单 哈希表、两数配对
BM51 数组中出现次数超过一半的数字 简单 摩尔投票法/哈希
BM52 数组中只出现一次的两个数字 中等 位运算、哈希
BM53 缺失的第一个正整数 中等 原地哈希、索引映射
BM54 三数之和 中等 排序+双指针/哈希

七、递归/回溯专题 (BM55-BM61)

7.1 核心知识点

  • 全排列
  • 子集
  • N皇后
  • 岛屿数量
  • 括号生成

7.2 Python代码模板

python 复制代码
# 回溯算法模板
def backtrack(路径, 选择列表):
    if 满足结束条件:
        result.add(路径)
        return
    for 选择 in 选择列表:
        做选择
        backtrack(路径, 选择列表)
        撤销选择

# 1. 全排列
class Solution:
    def permute(self, nums):
        result = []
        n = len(nums)
        
        def backtrack(path, used):
            if len(path) == n:
                result.append(path[:])
                return
            for i in range(n):
                if not used[i]:
                    used[i] = True
                    path.append(nums[i])
                    backtrack(path, used)
                    path.pop()
                    used[i] = False
        
        backtrack([], [False] * n)
        return result

# 2. 子集
class Solution:
    def subsets(self, nums):
        result = []
        n = len(nums)
        
        def backtrack(start, path):
            result.append(path[:])
            for i in range(start, n):
                path.append(nums[i])
                backtrack(i + 1, path)
                path.pop()
        
        backtrack(0, [])
        return result

# 3. N皇后
class Solution:
    def solveNQueens(self, n):
        result = []
        board = [['.' for _ in range(n)] for _ in range(n)]
        
        def isValid(row, col):
            for i in range(row):
                if board[i][col] == 'Q':
                    return False
            i, j = row - 1, col - 1
            while i >= 0 and j >= 0:
                if board[i][j] == 'Q':
                    return False
                i -= 1
                j -= 1
            i, j = row - 1, col + 1
            while i >= 0 and j < n:
                if board[i][j] == 'Q':
                    return False
                i -= 1
                j += 1
            return True
        
        def backtrack(row):
            if row == n:
                result.append([''.join(row) for row in board])
                return
            for col in range(n):
                if isValid(row, col):
                    board[row][col] = 'Q'
                    backtrack(row + 1)
                    board[row][col] = '.'
        
        backtrack(0)
        return result

# 4. 岛屿数量
class Solution:
    def numIslands(self, grid):
        if not grid:
            return 0
        m, n = len(grid), len(grid[0])
        count = 0
        
        def dfs(i, j):
            if i < 0 or i >= m or j < 0 or j >= n or grid[i][j] != '1':
                return
            grid[i][j] = '0'  # 标记已访问
            dfs(i+1, j)
            dfs(i-1, j)
            dfs(i, j+1)
            dfs(i, j-1)
        
        for i in range(m):
            for j in range(n):
                if grid[i][j] == '1':
                    count += 1
                    dfs(i, j)
        return count

7.3 题目列表

题号 题目名称 难度 核心考察知识点
BM55 没有重复项数字的全排列 中等 回溯、全排列
BM56 有重复项数字的全排列 中等 回溯、去重
BM57 岛屿数量 中等 DFS/BFS、连通块
BM58 字符串的排列 中等 回溯、字符串排列
BM59 N皇后问题 困难 回溯、剪枝
BM60 括号生成 中等 回溯、括号组合
BM61 矩阵最长递增路径 中等 记忆化搜索、DFS

八、动态规划专题 (BM62-BM82)

8.1 核心知识点

  • 状态定义: dp[i]或dp[i][j]的含义
  • 状态转移方程: 如何从子问题推导出当前问题
  • 初始化: base case
  • 遍历顺序: 确保计算当前状态时,依赖的状态已计算

8.2 Python代码模板

python 复制代码
# 1. 斐波那契数列 - 状态压缩
class Solution:
    def Fibonacci(self, n):
        if n <= 1:
            return n
        prev2, prev1 = 0, 1
        for i in range(2, n + 1):
            current = prev1 + prev2
            prev2, prev1 = prev1, current
        return prev1

# 2. 连续子数组最大和
class Solution:
    def FindGreatestSumOfSubArray(self, array):
        dp = [0] * len(array)
        dp[0] = array[0]
        max_sum = array[0]
        for i in range(1, len(array)):
            dp[i] = max(array[i], dp[i-1] + array[i])
            max_sum = max(max_sum, dp[i])
        return max_sum

# 3. 最长公共子序列 (LCS)
class Solution:
    def longestCommonSubsequence(self, text1, text2):
        m, n = len(text1), len(text2)
        dp = [[0] * (n + 1) for _ in range(m + 1)]
        for i in range(1, m + 1):
            for j in range(1, n + 1):
                if text1[i-1] == text2[j-1]:
                    dp[i][j] = dp[i-1][j-1] + 1
                else:
                    dp[i][j] = max(dp[i-1][j], dp[i][j-1])
        return dp[m][n]

# 4. 最长上升子序列
class Solution:
    def lengthOfLIS(self, nums):
        if not nums:
            return 0
        dp = [1] * len(nums)
        for i in range(1, len(nums)):
            for j in range(i):
                if nums[i] > nums[j]:
                    dp[i] = max(dp[i], dp[j] + 1)
        return max(dp)

# 5. 0-1背包问题
class Solution:
    def knapsack(self, weights, values, capacity):
        n = len(weights)
        dp = [0] * (capacity + 1)
        for i in range(n):
            for j in range(capacity, weights[i] - 1, -1):
                dp[j] = max(dp[j], dp[j - weights[i]] + values[i])
        return dp[capacity]

# 6. 完全背包(正序遍历)
class Solution:
    def complete_knapsack(self, weights, values, capacity):
        n = len(weights)
        dp = [0] * (capacity + 1)
        for i in range(n):
            for j in range(weights[i], capacity + 1):
                dp[j] = max(dp[j], dp[j - weights[i]] + values[i])
        return dp[capacity]

# 7. 股票问题 - 买卖股票的最佳时机
class Solution:
    def maxProfit(self, prices):
        if not prices:
            return 0
        min_price = prices[0]
        max_profit = 0
        for price in prices:
            min_price = min(min_price, price)
            max_profit = max(max_profit, price - min_price)
        return max_profit

# 8. 编辑距离
class Solution:
    def minDistance(self, word1, word2):
        m, n = len(word1), len(word2)
        dp = [[0] * (n + 1) for _ in range(m + 1)]
        for i in range(m + 1):
            dp[i][0] = i
        for j in range(n + 1):
            dp[0][j] = j
        for i in range(1, m + 1):
            for j in range(1, n + 1):
                if word1[i-1] == word2[j-1]:
                    dp[i][j] = dp[i-1][j-1]
                else:
                    dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1
        return dp[m][n]

8.3 题目列表

题号 题目名称 难度 核心考察知识点
BM62 斐波那契数列 入门 DP基础、递推
BM63 跳台阶 简单 DP、递推
BM64 最小花费爬楼梯 简单 DP、状态转移
BM65 最长公共子序列(二) 中等 二维DP、LCS
BM66 最长公共子串 中等 二维DP、子串
BM67 不同路径的数目(一) 简单 二维DP、路径计数
BM68 矩阵的最小路径和 中等 二维DP、路径DP
BM69 把数字翻译成字符串 中等 DP、字符串解码
BM70 兑换零钱(一) 中等 完全背包、DP
BM71 最长上升子序列(一) 中等 一维DP、LIS
BM72 连续子数组的最大和 简单 一维DP、最大子数组
BM73 最长回文子串 中等 中心扩展/DP
BM74 数字字符串转化成IP地址 中等 回溯/DP、字符串分割
BM75 编辑距离(一) 较难 二维DP、经典问题
BM76 正则表达式匹配 困难 二维DP、复杂状态
BM77 最长的括号子串 中等 栈/DP、括号匹配
BM78 打家劫舍(一) 中等 一维DP、状态转移
BM79 打家劫舍(二) 中等 一维DP、环形数组
BM80 买卖股票的最好时机(一) 简单 一维DP、股票问题
BM81 买卖股票的最好时机(二) 中等 一维DP、无限交易
BM82 买卖股票的最好时机(三) 中等 二维DP、有限交易

九、字符串专题 (BM83-BM86)

9.1 核心知识点

  • 字符串操作
  • 最长公共前缀
  • IP地址验证
  • 大数运算

9.2 Python代码模板

python 复制代码
# 1. 最长公共前缀
class Solution:
    def longestCommonPrefix(self, strs):
        if not strs:
            return ""
        prefix = strs[0]
        for s in strs[1:]:
            while not s.startswith(prefix):
                prefix = prefix[:-1]
                if not prefix:
                    return ""
        return prefix

# 2. 大数加法
class Solution:
    def solve(self, s, t):
        result = []
        i, j = len(s) - 1, len(t) - 1
        carry = 0
        while i >= 0 or j >= 0 or carry:
            num1 = int(s[i]) if i >= 0 else 0
            num2 = int(t[j]) if j >= 0 else 0
            total = num1 + num2 + carry
            result.append(str(total % 10))
            carry = total // 10
            i -= 1
            j -= 1
        return ''.join(reversed(result))

9.3 题目列表

题号 题目名称 难度 核心考察知识点
BM83 字符串变形 简单 字符串操作、空格处理
BM84 最长公共前缀 简单 字符串比较、纵向扫描
BM85 验证IP地址 中等 字符串处理、IP验证
BM86 大数加法 简单 字符串模拟、大数运算

十、双指针专题 (BM87-BM94)

10.1 核心知识点

  • 对撞指针
  • 快慢指针
  • 滑动窗口

10.2 Python代码模板

python 复制代码
# 1. 对撞指针 - 两数之和
class Solution:
    def twoSum(self, nums, target):
        left, right = 0, len(nums) - 1
        while left < right:
            current = nums[left] + nums[right]
            if current == target:
                return [left + 1, right + 1]
            elif current < target:
                left += 1
            else:
                right -= 1
        return []

# 2. 滑动窗口 - 最长无重复子串
class Solution:
    def lengthOfLongestSubstring(self, s):
        char_index = {}
        left = 0
        max_len = 0
        for right, char in enumerate(s):
            if char in char_index and char_index[char] >= left:
                left = char_index[char] + 1
            char_index[char] = right
            max_len = max(max_len, right - left + 1)
        return max_len

# 3. 接雨水
class Solution:
    def trap(self, height):
        if not height:
            return 0
        left, right = 0, len(height) - 1
        left_max = right_max = 0
        water = 0
        while left < right:
            if height[left] < height[right]:
                if height[left] >= left_max:
                    left_max = height[left]
                else:
                    water += left_max - height[left]
                left += 1
            else:
                if height[right] >= right_max:
                    right_max = height[right]
                else:
                    water += right_max - height[right]
                right -= 1
        return water

10.3 题目列表

题号 题目名称 难度 核心考察知识点
BM87 合并两个有序的数组 简单 双指针、从后向前
BM88 判断是否为回文字符串 简单 双指针、回文判断
BM89 合并区间 中等 排序、双指针、区间合并
BM90 最小覆盖子串 困难 滑动窗口、双指针
BM91 反转字符串 简单 双指针、原地交换
BM92 最长无重复子数组 中等 滑动窗口、哈希
BM93 盛水最多的容器 中等 双指针、面积计算
BM94 接雨水问题 中等 双指针/单调栈、接雨水

十一、贪心专题 (BM95-BM96)

11.1 核心知识点

  • 区间调度
  • 贪心策略

11.2 题目列表

题号 题目名称 难度 核心考察知识点
BM95 分糖果问题 中等 贪心、两次遍历
BM96 主持人调度(二) 中等 贪心、区间调度

十二、模拟/设计专题 (BM97-BM101)

12.1 核心知识点

  • 数组旋转
  • 螺旋矩阵
  • LRU/LFU缓存设计

12.2 Python代码模板

python 复制代码
# 1. 旋转数组
class Solution:
    def rotate(self, nums, k):
        k %= len(nums)
        nums[:] = nums[-k:] + nums[:-k]

# 2. 螺旋矩阵
class Solution:
    def spiralOrder(self, matrix):
        if not matrix:
            return []
        result = []
        top, bottom = 0, len(matrix) - 1
        left, right = 0, len(matrix[0]) - 1
        while top <= bottom and left <= right:
            for i in range(left, right + 1):
                result.append(matrix[top][i])
            top += 1
            for i in range(top, bottom + 1):
                result.append(matrix[i][right])
            right -= 1
            if top <= bottom:
                for i in range(right, left - 1, -1):
                    result.append(matrix[bottom][i])
                bottom -= 1
            if left <= right:
                for i in range(bottom, top - 1, -1):
                    result.append(matrix[i][left])
                left += 1
        return result

# 3. LRU缓存
from collections import OrderedDict
class Solution:
    def __init__(self, capacity):
        self.capacity = capacity
        self.cache = OrderedDict()
    
    def get(self, key):
        if key not in self.cache:
            return -1
        self.cache.move_to_end(key)
        return self.cache[key]
    
    def put(self, key, value):
        if key in self.cache:
            self.cache.move_to_end(key)
        self.cache[key] = value
        if len(self.cache) > self.capacity:
            self.cache.popitem(last=False)

12.3 题目列表

题号 题目名称 难度 核心考察知识点
BM97 旋转数组 简单 三次反转、数组操作
BM98 螺旋矩阵 中等 模拟、边界控制
BM99 顺时针旋转矩阵 中等 矩阵转置、翻转
BM100 设计LRU缓存结构 中等 哈希+双向链表
BM101 设计LFU缓存结构 困难 哈希+多链表

附录:时间/空间复杂度速查表

算法类型 典型时间复杂度 空间复杂度
数组遍历 O(n) O(1)
双指针 O(n) O(1)
二分查找 O(log n) O(1)
哈希查找 O(1) O(n)
快速排序 O(n log n)平均 O(log n)
归并排序 O(n log n) O(n)
堆排序 O(n log n) O(1)
二叉树遍历 O(n) O(h)
图的BFS/DFS O(V+E) O(V)
动态规划 O(n)或O(n²) O(n)或O(n²)
回溯算法 O(2ⁿ)或O(n!) O(n)

参考资源

相关推荐
项目申报小狂人1 小时前
提出了一种带双向搜索的粒子群优化算法,一种基于双四元数运动优化的新型无人机3D路径规划方法及应用
算法·3d·无人机
2301_815901971 小时前
Go语言怎么做秒杀系统_Go语言秒杀系统实战教程【实用】
jvm·数据库·python
2303_821287381 小时前
C#怎么实现WebAPI版本控制_C#如何管理不同接口版本【核心】
jvm·数据库·python
woxihuan1234561 小时前
如何使用MongoDB按前缀模糊查询_正则表达式^与索引利用
jvm·数据库·python
2401_824697661 小时前
Golang怎么用Go实现数据导入导出平台_Golang如何支持CSV和Excel格式的批量数据导入导出【实战】
jvm·数据库·python
得一录1 小时前
TradingAgents金融股票分析的最小实现
开发语言·数据库·人工智能·python
阿正呀1 小时前
C#怎么清空Dictionary字典_C#如何管理内存集合【基础】
jvm·数据库·python
大大杰哥1 小时前
leetcode hot100(3)子串
c++·算法·leetcode
yuanpan1 小时前
Python 与 Conda 编程实战指南:从环境配置到项目运行完整入门
开发语言·python·conda