题目描述
在生物信息学中,编辑距离(Edit Distance)是一个重要的概念,用于衡量两个字符串之间的相似度。编辑距离是指将一个字符串转换为另一个字符串所需的最少编辑操作次数,编辑操作包括插入、删除和替换。 解题思路
-
定义状态:
- 使用一个二维数组
dp,其中dp[i][j]表示将字符串dna1的前i个字符转换为字符串dna2的前j个字符所需的最少编辑操作次数。
- 使用一个二维数组
-
初始化:
dp[0][j]表示将空字符串转换为dna2的前j个字符,需要j次插入操作。dp[i][0]表示将dna1的前i个字符转换为空字符串,需要i次删除操作。
-
状态转移:
-
如果
dna1[i-1] == dna2[j-1],则dp[i][j] = dp[i-1][j-1],即不需要任何操作。 -
否则,
dp[i][j]可以通过以下三种操作之一得到:- 插入:
dp[i][j-1] + 1 - 删除:
dp[i-1][j] + 1 - 替换:
dp[i-1][j-1] + 1
- 插入:
-
取这三种操作的最小值作为
dp[i][j]。
-
-
最终结果:
-
dp[m][n]即为将dna1转换为dna2所需的最少编辑操作次数,其中m和n分别是dna1和dna2的长度 -
public class Main { public static int solution(String dna1, String dna2) { int m = dna1.length(); int n = dna2.length();
// 创建一个 (m+1) x (n+1) 的二维数组 dp int[][] dp = new int[m + 1][n + 1];
// 初始化 dp 数组 for (int i = 0; i <= m; i++) { dp[i][0] = i; } for (int j = 0; j <= n; j++) { dp[0][j] = j; }
// 填充 dp 数组 for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { if (dna1.charAt(i - 1) == dna2.charAt(j - 1)) { dp[i][j] = dp[i - 1][j - 1]; } else { dp[i][j] = Math.min(dp[i - 1][j - 1], Math.min(dp[i - 1][j], dp[i][j - 1])) + 1; } } }
// 返回最终结果 return dp[m][n]; }
public static void main(String[] args) { // 你可以添加更多测试用例 System.out.println(solution("AGCTTAGC", "AGCTAGCT") == 2); System.out.println(solution("AGCCGAGC", "GCTAGCT") == 4); } } 知识总结
-
新知识点
-
动态规划(Dynamic Programming) :
- 动态规划是一种通过将问题分解为子问题并存储子问题的解来解决复杂问题的方法。编辑距离问题就是一个典型的动态规划问题。
-
二维数组的应用:
- 在动态规划中,二维数组常用于存储状态转移的结果,特别是在处理两个字符串之间的关系时。 理解与建议
- 理解动态规划的核心思想:动态规划的关键在于找到状态转移方程,并正确初始化边界条件。通过逐步填充二维数组,可以有效地解决复杂问题。
- 多练:动态规划问题通常较为复杂,建议多练习类似的题目,加深对动态规划思想的理解。
学习计划
高效学习方法
-
制定刷题计划:
- 每天固定时间刷题,逐步增加题目难度。可以从简单的动态规划问题开始,逐步过渡到更复杂的问题。
-
利用错题进行针对性学习:
- 记录错题,分析错误原因,并针对性地进行复习。可以通过豆包MarsCode AI的错题本功能,方便地管理和复习错题。
-
定期总结:
- 每周或每月进行一次总结,回顾所学知识点,整理笔记,加深记忆。
工具运用 结合其他学习资源
-
在线课程:
- 结合在线课程学习动态规划的基础知识,如Coursera上的算法课程。
-
书籍:
- 阅读相关书籍,如《算法导论》,深入理解动态规划的原理和应用。
-
社区讨论:
- 参与编程社区的讨论,如LeetCode论坛,与其他学习者交流经验,解决疑惑。