小R正在研究DNA序列,他需要一个函数来计算将一个受损DNA序列(dna1)转换成一个未受损序列(dna2)所需的最少编辑步骤。编辑步骤包括:增加一个碱基、删除一个碱基或替换一个碱基。
测试样例
样例1:
输入:
dna1 = "AGT",dna2 = "AGCT"
输出:1
样例2:
输入:
dna1 = "AACCGGTT",dna2 = "AACCTTGG"
输出:4
样例3:
输入:
dna1 = "ACGT",dna2 = "TGC"
输出:3
样例4:
输入:
dna1 = "A",dna2 = "T"
输出:1
样例5:
输入:
dna1 = "GGGG",dna2 = "TTTT"
输出:4
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class Main {
public static int solution(String dna1, String dna2) {
int m = dna1.length();
int n = dna2.length();
// 创建一个二维数组 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;
}
}
}
MarsCode AI
MarsCode AI
好的,我们可以使用动态规划来解决这个问题。动态规划可以帮助我们找到从 dna1 到 dna2 的最小操作步骤数。
解题思路
-
定义状态:我们可以使用一个二维数组
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
- 插入:
-
取这三种操作中的最小值。
-
代码提示
java
public class Main {
public static int
solution(String dna1,
String dna2) {
int m = dna1.
length();
int n = dna2.
length();
// 创建一个二维数组
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);
}
}
关键步骤解释
- 初始化:
dp[i][0]和dp[0][j]的初始化是为了处理边界情况。 - 状态转移:通过比较
dna1和dna2的当前字符,决定是否需要进行插入、删除或替换操作,并取最小值。 - 返回结果:最终结果存储在
dp[m][n]中,表示将dna1转换为dna2所需的最小操作步骤数。
你可以根据这个框架继续完善代码,或者根据需要进行调整。
动态规划算法如何应用在这个问题中?
给我一些代码提示
帮我检查一下编辑区的代码