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

题单链接: 牛客top101
题目总数: 101道
题单定位: 基于牛客面经汇总分析整理出的面试常考算法题,完成本题单可解决面试中约70%的代码题
题单模式: 核心代码模式
目录
- 题单概览
- 链表专题 (BM1-BM16)
- 二分查找/排序专题 (BM17-BM22)
- 二叉树专题 (BM23-BM41)
- 堆/栈/队列专题 (BM42-BM49)
- 哈希专题 (BM50-BM54)
- 递归/回溯专题 (BM55-BM61)
- 动态规划专题 (BM62-BM82)
- 字符串专题 (BM83-BM86)
- 双指针专题 (BM87-BM94)
- 贪心专题 (BM95-BM96)
- 模拟/设计专题 (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代码模板
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def ReverseList(self, head):
pre = None
cur = head
while cur:
tmp = cur.next
cur.next = pre
pre = cur
cur = tmp
return pre
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
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
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
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代码模板
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
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]
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代码模板
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def preorderTraversal(self, root):
if not root:
return []
return [root.val] + self.preorderTraversal(root.left) + self.preorderTraversal(root.right)
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
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
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)
class Solution:
def maxDepth(self, root):
if not root:
return 0
return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right))
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代码模板
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()
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]
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
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代码模板
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 []
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
class Solution:
def singleNumber(self, nums):
xor = 0
for num in nums:
xor ^= num
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 核心知识点
7.2 Python代码模板
def backtrack(路径, 选择列表):
if 满足结束条件:
result.add(路径)
return
for 选择 in 选择列表:
做选择
backtrack(路径, 选择列表)
撤销选择
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
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
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
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代码模板
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
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
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]
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)
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]
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]
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
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 核心知识点
9.2 Python代码模板
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
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代码模板
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 []
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
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 核心知识点
12.2 Python代码模板
class Solution:
def rotate(self, nums, k):
k %= len(nums)
nums[:] = nums[-k:] + nums[:-k]
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
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) |
参考资源
所有评论(0)