当前位置: 首页 > news >正文

东华大学OJ复试题解析:字符串匹配与动态规划实战

1. 项目背景与目标

最近在准备东华大学计算机专业的研究生复试,发现他们的在线评测系统(OJ)题目很有特点。特别是第12套题,第一次做的时候踩了不少坑,这次二刷特意做了详细复盘。这套题主要考察数据结构与算法的实际应用能力,涉及字符串处理、动态规划等核心知识点。

作为计算机专业考研复试的必考内容,OJ题目的熟练度直接影响复试成绩。通过系统性地整理错题和优化解法,不仅能提升编程能力,还能培养解决工程问题的思维模式。下面我就把这套题的解题思路、常见陷阱和优化技巧完整分享出来。

2. 题目分析与解题思路

2.1 第一题:字符串模式匹配

这道题要求实现带通配符的字符串匹配算法。与标准KMP算法不同,题目中的通配符"?"可以匹配任意单个字符,"*"可以匹配任意长度字符串(包括空串)。

def isMatch(s: str, p: str) -> bool: m, n = len(s), len(p) dp = [[False]*(n+1) for _ in range(m+1)] dp[0][0] = True for j in range(1, n+1): if p[j-1] == '*': dp[0][j] = dp[0][j-1] for i in range(1, m+1): for j in range(1, n+1): if p[j-1] == s[i-1] or p[j-1] == '?': dp[i][j] = dp[i-1][j-1] elif p[j-1] == '*': dp[i][j] = dp[i][j-1] or dp[i-1][j] return dp[m][n]

注意:初始化时dp[0][0]=True表示两个空字符串匹配,对于模式串开头的多个'*',需要特殊处理它们可以匹配空字符串的情况。

2.2 第二题:二叉树路径求和

题目给出一个二叉树,要求找出所有从根节点到叶子节点的路径,使得路径上节点值之和等于给定目标值。这是典型的DFS应用场景。

class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def pathSum(root: TreeNode, target: int) -> List[List[int]]: res = [] def dfs(node, path, remain): if not node: return path.append(node.val) if not node.left and not node.right and remain == node.val: res.append(list(path)) dfs(node.left, path, remain - node.val) dfs(node.right, path, remain - node.val) path.pop() dfs(root, [], target) return res

常见错误:

  1. 忘记在递归返回前弹出当前节点(path.pop())
  2. 没有判断叶子节点条件(not node.left and not node.right)
  3. 直接添加path到res而没有创建新列表(会导致后续修改影响结果)

3. 动态规划专题

3.1 最长递增子序列

这道题要求找出数组中最长的严格递增子序列的长度。经典解法时间复杂度是O(n²),但可以用二分查找优化到O(nlogn)。

def lengthOfLIS(nums: List[int]) -> int: tails = [] for num in nums: left, right = 0, len(tails) while left < right: mid = (left + right) // 2 if tails[mid] < num: left = mid + 1 else: right = mid if left == len(tails): tails.append(num) else: tails[left] = num return len(tails)

优化思路:

  1. tails数组维护当前长度的最小末尾值
  2. 对于每个新元素,用二分查找确定它在tails中的位置
  3. 要么扩展tails数组,要么替换某个位置的元素

3.2 零钱兑换问题

给定不同面额的硬币和一个总金额,计算可以凑成总金额的最少硬币数。这是典型的完全背包问题。

def coinChange(coins: List[int], amount: int) -> int: dp = [float('inf')] * (amount + 1) dp[0] = 0 for coin in coins: for i in range(coin, amount + 1): dp[i] = min(dp[i], dp[i - coin] + 1) return dp[amount] if dp[amount] != float('inf') else -1

易错点:

  1. 初始值设为无穷大表示不可达(除了dp[0]=0)
  2. 内循环从coin开始,避免数组越界
  3. 最后需要判断是否有解(是否仍为无穷大)

4. 图论问题解析

4.1 课程安排问题

典型的拓扑排序应用,判断课程安排是否存在循环依赖。可以用Kahn算法或DFS实现。

def canFinish(numCourses: int, prerequisites: List[List[int]]) -> bool: graph = [[] for _ in range(numCourses)] in_degree = [0] * numCourses for course, pre in prerequisites: graph[pre].append(course) in_degree[course] += 1 queue = [i for i in range(numCourses) if in_degree[i] == 0] count = 0 while queue: node = queue.pop() count += 1 for neighbor in graph[node]: in_degree[neighbor] -= 1 if in_degree[neighbor] == 0: queue.append(neighbor) return count == numCourses

关键步骤:

  1. 构建邻接表和入度数组
  2. 初始化队列(入度为0的节点)
  3. 不断移除队列中的节点并更新邻居的入度
  4. 最后检查是否所有节点都被处理

4.2 岛屿数量问题

给定二维网格,计算其中岛屿的数量。经典连通分量问题,DFS/BFS均可。

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 c < 0 or r >= rows or c >= cols or grid[r][c] != '1': 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

优化技巧:

  1. 直接在原数组上标记访问过的位置(节省空间)
  2. 四个方向的DFS可以用循环简化
  3. 遇到'1'时立即进行标记和扩展

5. 高频考点与应试技巧

5.1 时间复杂度分析

东华OJ题常要求分析算法复杂度。几个常见复杂度及其场景:

复杂度典型算法适用场景
O(1)哈希查找常数时间操作
O(logn)二分查找有序数据查找
O(n)线性扫描遍历数组/链表
O(nlogn)快速排序大多数排序算法
O(n²)冒泡排序简单但低效算法
O(2ⁿ)全排列暴力穷举

5.2 代码风格建议

  1. 变量命名要有意义(避免用temp, a, b等)
  2. 适当添加注释解释复杂逻辑
  3. 保持一致的缩进风格(4个空格)
  4. 函数长度控制在30行以内
  5. 边界条件要单独测试(空输入、极值等)

5.3 调试技巧

  1. 使用print调试关键变量值
  2. 对样例输入手动模拟算法流程
  3. 编写测试用例覆盖各种边界情况
  4. 利用OJ提供的错误信息定位问题
  5. 遇到超时先检查死循环和复杂度

6. 复试准备建议

  1. 基础巩固:重点复习数据结构(树、图、堆)和算法(排序、查找、DP)
  2. 刷题策略:按专题练习(字符串、数组、链表等),每个专题10-15题
  3. 错题整理:建立错题本,记录错误原因和正确解法
  4. 模拟练习:使用计时功能模拟真实考试环境
  5. 代码规范:平时就注意书写规范,避免考试时扣分

这套OJ题目很好地覆盖了复试常见考点,建议至少刷3遍:

  • 第一遍:熟悉题目,记录难点
  • 第二遍:优化解法,分析复杂度
  • 第三遍:模拟考试,提升速度
http://www.jsqmd.com/news/1356593/

相关文章:

  • NepNep
  • nano banana pro 怎么用?甜甜圈API 三十行跑通 nano banana pro(含重试与异步并发)
  • 3步掌握跨设备键鼠共享:开源KVM终极方案
  • 3种终极方案:qmc-decoder助你快速解锁QQ音乐加密文件
  • 2026 年当下,莱芜有实力的AI全域获客公司哪家靠谱,别再天天蹲线索了,这玩意儿悄悄把流量全捏在手里,不用再费心拓客-抖盈网络 - 企业推荐管【认证】
  • 美团酒店/医药/闪购 商家端mtgsig最新算法分析
  • 从零掌握CLI工具:OpenCode CLI安装、核心命令与工作流集成指南
  • 基于状态驱动与事件总线的复杂互动叙事引擎实战
  • AI绘画进阶:Flux.1-schnell模型、Krea风格库与深度图控制实战指南
  • 《P14076 [GESP202509 六级] 货物运输》
  • 聊聊Starrocks的数据导入与避坑实践
  • 水电表物联网化:TCP2HTTP网关方案与协议转换实践
  • AI服务API集成实战:从账户支付到代码调用的完整指南
  • Flutter在OpenHarmony上开发个人理财App实践
  • Flink数据倾斜问题诊断与十二种解决方案
  • 基于AI语音技术的视频内容本地化:从ASR到TTS的完整实践指南
  • STDF Viewer:半导体测试数据可视化终极指南,5分钟快速掌握复杂数据分析
  • 如何用免费开源软件TuxGuitar制作专业吉他谱:5个简单技巧
  • 茶叶病害早期检测的图像数据集
  • Axure RP中文语言包:3分钟告别英文界面,提升原型设计效率
  • 国内零门槛部署本地AI编程助手:Codex框架与DeepSeek模型实战教程
  • AI内容审核攻防实战:从对抗样本生成到鲁棒模型训练
  • 2026精选青岛市值得信赖的抹光机直销厂家联系指南 - 装修教育财税推荐2026
  • 工作流引擎实战:从编辑到执行的完整生命周期解析
  • NR37-CP的ERLE极限:固定null与自适应ENC的分工边界
  • 网络安全自学路线与职业发展指南
  • SkyWalking与Istio集成:微服务监控最佳实践
  • 栖岛OAuth2.0登录对接实战指南与避坑技巧
  • 虚假工作预测数据集
  • AI图表分析提示词实战指南:从模糊指令到精准洞察