1. 东华复试OJ每日3题打卡的背景与价值
作为一名经历过东华大学计算机考研复试的过来人,我深知OJ(Online Judge)刷题在复试环节的重要性。东华大学的复试机试环节通常会设置3-5道编程题,难度从基础语法考察到中等难度算法题不等。而"每日3题打卡"这种训练方式,正是针对复试特点设计的有效备考策略。
在备考期间保持每日3题的训练强度,能够带来三个核心价值:
- 保持编程手感:避免长时间不写代码导致的手生问题
- 覆盖题型广度:通过每日不同方向的题目训练,全面掌握常见算法题型
- 培养时间意识:3题/天的训练量接近实际考试强度,有助于培养时间管理能力
我特别建议从复试前2-3个月开始这种打卡训练,这样既能保证训练的系统性,又不会因为战线过长导致疲惫。下面我将分享46~48天的具体题目复盘,这些题目都是我从东华历年真题和类似高校复试题库中精选出来的典型题目。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 第46天打卡题目详解
2.1 题目一:字符串压缩算法
这是一道经典的字符串处理题目,要求实现类似"aaabbbcc"→"a3b3c2"的压缩算法。这道题考察了以下几个关键点:
- 字符串遍历与状态记录:
python复制def compress_string(s):
if not s:
return s
result = []
current_char = s[0]
count = 1
for char in s[1:]:
if char == current_char:
count += 1
else:
result.append(current_char + str(count))
current_char = char
count = 1
result.append(current_char + str(count))
compressed = ''.join(result)
return compressed if len(compressed) < len(s) else s
注意:在实际编码测试时,要特别注意空字符串和单字符字符串的特殊情况处理。我在第一次提交时就因为漏掉了空字符串判断而丢分。
2.2 题目二:二叉树的最小深度
这道题考察的是对二叉树遍历的理解。与求最大深度不同,最小深度需要考虑以下特殊情况:
python复制def minDepth(root):
if not root:
return 0
if not root.left and not root.right:
return 1
left_depth = minDepth(root.left) if root.left else float('inf')
right_depth = minDepth(root.right) if root.right else float('inf')
return 1 + min(left_depth, right_depth)
关键点在于当某子树为空时,不能简单地取min(left, right),否则会得到错误的最小深度。这个细节在面试中经常被用作区分点。
2.3 题目三:矩阵中的最长递增路径
这是一道DFS+记忆化的典型题目,难度中等偏上:
python复制def longestIncreasingPath(matrix):
if not matrix:
return 0
m, n = len(matrix), len(matrix[0])
memo = [[0]*n for _ in range(m)]
directions = [(0,1),(1,0),(0,-1),(-1,0)]
def dfs(i, j):
if memo[i][j] != 0:
return memo[i][j]
max_len = 1
for dx, dy in directions:
x, y = i + dx, j + dy
if 0 <= x < m and 0 <= y < n and matrix[x][y] > matrix[i][j]:
max_len = max(max_len, 1 + dfs(x, y))
memo[i][j] = max_len
return max_len
return max(dfs(i, j) for i in range(m) for j in range(n))
这道题的优化关键在于记忆化搜索,避免重复计算。在实际编码时,我建议先写出基础DFS版本,再添加记忆化优化,这样思路更清晰。
3. 第47天打卡题目解析
3.1 题目一:有效的括号字符串
这道题是经典括号匹配问题的变种,引入了通配符"*"的概念:
python复制def checkValidString(s):
low = high = 0
for char in s:
if char == '(':
low += 1
high += 1
elif char == ')':
low = max(low - 1, 0)
high -= 1
if high < 0:
return False
else: # '*'
low = max(low - 1, 0)
high += 1
return low == 0
这个解法使用了贪心思想,维护当前可能的最小和最大开括号数。我在初次遇到这个问题时,尝试用栈来解决,发现处理'*'时情况过于复杂。后来才了解到这种更优雅的双变量追踪解法。
3.2 题目二:旋转图像
经典的矩阵旋转问题,考察对二维数组索引的理解:
python复制def rotate(matrix):
n = len(matrix)
# 转置矩阵
for i in range(n):
for j in range(i, n):
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
# 反转每一行
for i in range(n):
matrix[i] = matrix[i][::-1]
提示:面试时可能会要求不适用额外空间完成旋转。这个解法先转置再水平翻转的思路非常巧妙,需要熟练掌握。
3.3 题目三:单词搜索
典型的回溯算法应用题:
python复制def exist(board, word):
def backtrack(i, j, k):
if k == len(word):
return True
if i < 0 or i >= len(board) or j < 0 or j >= len(board[0]) or board[i][j] != word[k]:
return False
temp = board[i][j]
board[i][j] = '#'
found = (backtrack(i+1, j, k+1) or
backtrack(i-1, j, k+1) or
backtrack(i, j+1, k+1) or
backtrack(i, j-1, k+1))
board[i][j] = temp
return found
for i in range(len(board)):
for j in range(len(board[0])):
if backtrack(i, j, 0):
return True
return False
这道题的关键在于回溯时标记已访问的单元格,并在回溯结束后恢复原始值。我在实际编码时,最初忘记恢复board[i][j]的值,导致后续搜索出错。
4. 第48天打卡题目精讲
4.1 题目一:最长连续序列
这道题要求找出未排序数组中的最长连续数字序列:
python复制def longestConsecutive(nums):
num_set = set(nums)
max_streak = 0
for num in num_set:
if num - 1 not in num_set:
current_num = num
current_streak = 1
while current_num + 1 in num_set:
current_num += 1
current_streak += 1
max_streak = max(max_streak, current_streak)
return max_streak
这个O(n)时间复杂度的解法非常巧妙,通过检查num-1是否存在来判断是否可以作为序列起点。我在第一次做时使用了排序解法,虽然正确但时间复杂度不理想。
4.2 题目二:打家劫舍III
这是动态规划在二叉树上的应用:
python复制def rob(root):
def helper(node):
if not node:
return (0, 0)
left = helper(node.left)
right = helper(node.right)
rob_current = node.val + left[1] + right[1]
not_rob_current = max(left) + max(right)
return (rob_current, not_rob_current)
return max(helper(root))
这个解法返回一个元组,第一个元素表示抢劫当前节点的最大收益,第二个表示不抢劫当前节点的最大收益。这种树形DP的思路在面试中经常出现,需要重点掌握。
4.3 题目三:课程表
拓扑排序的经典应用:
python复制def canFinish(numCourses, prerequisites):
adj = [[] for _ in range(numCourses)]
indegree = [0] * numCourses
for course, prereq in prerequisites:
adj[prereq].append(course)
indegree[course] += 1
queue = []
for i in range(numCourses):
if indegree[i] == 0:
queue.append(i)
count = 0
while queue:
node = queue.pop(0)
count += 1
for neighbor in adj[node]:
indegree[neighbor] -= 1
if indegree[neighbor] == 0:
queue.append(neighbor)
return count == numCourses
这道题的关键在于维护入度表和邻接表。我在实际编码时,最初混淆了邻接表的方向,导致结果错误。建议在纸上画出示例图,明确边的方向。
5. 打卡训练的高效方法
经过46-48天的打卡训练,我总结出以下几点高效训练建议:
- 错题分类整理:将做错的题目按算法类型分类,找出自己的薄弱环节
- 时间控制:每道题控制在25分钟内完成,模拟真实考试环境
- 多种解法:对每道题尝试至少两种解法,比较时间空间复杂度
- 代码规范:保持一致的代码风格,添加必要注释,方便面试时展示
我个人的一个实用技巧是建立"高频考点表",统计不同算法出现的频率。例如在东华复试中,动态规划和DFS/BFS出现的频率明显高于其他算法,这帮助我更有针对性地分配复习时间。
在训练后期,我还会进行"限时三题连做"的模拟测试,即连续完成三道不同难度的题目,总时间控制在90分钟内。这种高强度训练显著提升了我的编码速度和一次通过率。
