☰
矩阵路径、课程调度与编辑距离的算法解析
2026/10/26 16:59:32 网站建设 项目流程

1. 题目背景与解题思路

2026年2月11日这组OJ题目编号69-71,从编号规律来看应该属于某个在线判题系统的中级难度题目。这类题目通常考察数据结构与算法的综合应用能力,特别是针对特定问题的优化解法。

根据我的刷题经验,这类连续编号的题目往往存在某种内在联系。可能是:

  • 同一类问题的不同变种(如二叉树遍历的三种方式)
  • 难度递进的相关问题(如从暴力解法到动态规划优化)
  • 使用相同数据结构的多个应用场景

2. 题目69:矩阵中的最长递增路径

2.1 问题描述

(典型描述示例)给定一个m×n的整数矩阵,找出最长严格递增路径的长度。对于每个单元格,你可以向上下左右四个方向移动。

示例: 输入:matrix = [ [9,9,4], [6,6,8], [2,1,1] ] 输出:4 (最长路径是1→2→6→9)

2.2 解题思路

这类矩阵搜索问题通常有几种经典解法:

  1. DFS+记忆化:时间复杂度O(mn)
def longestIncreasingPath(matrix): if not matrix: return 0 m, n = len(matrix), len(matrix[0]) memo = [[0]*n for _ in range(m)] def dfs(i,j): if memo[i][j]: return memo[i][j] for x,y in [(i+1,j),(i-1,j),(i,j+1),(i,j-1)]: if 0<=x<m and 0<=y<n and matrix[x][y]>matrix[i][j]: memo[i][j] = max(memo[i][j], dfs(x,y)) memo[i][j] += 1 return memo[i][j] return max(dfs(i,j) for i in range(m) for j in range(n))
  1. 拓扑排序:将矩阵视为有向图,统计入度后分层剥离

2.3 优化技巧

  • 记忆化存储时可以用原矩阵作为visited标记
  • 方向数组用dx=[1,-1,0,0], dy=[0,0,1,-1]更高效
  • Python中可以functools.lru_cache实现自动记忆化

3. 题目70:课程安排III

3.1 问题描述

有n门课程,课程i需要在duration[i]天内完成,并且必须在lastDay[i]之前完成。求最多可以安排多少门课程。

示例: 输入:courses = [[100,200],[200,1300],[1000,1250],[2000,3200]] 输出:3

3.2 贪心算法实现

这类调度问题通常需要按某种规则排序后贪心处理:

import heapq def scheduleCourse(courses): courses.sort(key=lambda x: x[1]) heap = [] time = 0 for dur, end in courses: if time + dur <= end: heapq.heappush(heap, -dur) time += dur elif heap and -heap[0] > dur: time += dur + heapq.heappop(heap) heapq.heappush(heap, -dur) return len(heap)

3.3 关键点分析

  1. 按截止时间排序是贪心选择的基础
  2. 使用最大堆(通过存储负数实现)维护当前已选课程
  3. 当遇到冲突时,替换掉持续时间最长的课程

4. 题目71:编辑距离

4.1 经典动态规划问题

给定两个单词word1和word2,计算将word1转换成word2所需的最少操作数。允许的操作:

  • 插入一个字符
  • 删除一个字符
  • 替换一个字符

4.2 DP表格解法

def minDistance(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] = 1 + min( dp[i-1][j], # 删除 dp[i][j-1], # 插入 dp[i-1][j-1] # 替换 ) return dp[m][n]

4.3 空间优化

可以优化到O(n)空间,只保留前一行和当前行的状态:

def minDistance(word1, word2): m, n = len(word1), len(word2) prev = [j for j in range(n+1)] for i in range(1, m+1): curr = [i]*(n+1) for j in range(1, n+1): if word1[i-1] == word2[j-1]: curr[j] = prev[j-1] else: curr[j] = 1 + min( prev[j], # 删除 curr[j-1], # 插入 prev[j-1] # 替换 ) prev = curr return prev[n]

5. 刷题经验分享

5.1 调试技巧

  • 对于DP问题,先打印出完整的DP表格验证状态转移
  • 使用小规模测试用例(如空输入、单元素)检查边界条件
  • 在OJ平台超时时,本地用大随机数据测试

5.2 复杂度分析要点

  • 矩阵问题要考虑行列双重循环
  • 带排序的解法要加上排序的复杂度
  • 递归解法要明确递归深度和每层复杂度

5.3 代码模板整理

建议将以下模板保存为代码片段:

  1. 方向数组:dirs = [(1,0),(-1,0),(0,1),(0,-1)]
  2. 堆的使用:import heapq;heapq.heappush/pop
  3. DP表格初始化:dp = [[0]*n for _ in range(m)]

6. 同类题目推荐

如果想继续巩固这些题型,可以尝试:

  • 矩阵类:329(本题原型)、200岛屿数量
  • 贪心调度:630课程表III、1353最多可以参加的会议数目
  • 编辑距离:72(本题)、161相隔一个字符

刷题时注意总结题型特征,比如看到"最长/最短"、"最少操作"等关键词,就能快速联想到相应解法。这三道题虽然表面不同,但都体现了算法竞赛中的核心思维:如何将问题转化为经典模型,以及如何优化基础解法。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询