Skip to content

Commit 95d6b14

Browse files
committed
字符串的动态规划系列
1 parent 11be1ba commit 95d6b14

File tree

5 files changed

+115
-0
lines changed

5 files changed

+115
-0
lines changed

leetcode_Java/DoneTitle.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,16 @@
7575
538. 把二叉搜索树转换为累加树
7676
543. 二叉树的直径
7777
560. 和为 K 的子数组
78+
583. 两个字符串的删除操作
7879
589. N叉树的前序遍历
7980
617. 合并二叉树
8081
674. 最长连续递增序列
8182
695. 岛屿的最大面积
8283
698. 划分为k个相等的子集
84+
712. 两个字符串的最小ASCII删除和
8385
714. 买卖股票的最佳时机含手续费
86+
718. 最长重复子数组
8487
1020. 飞地的数量
88+
1143. 最长公共子序列
8589
1254. 统计封闭岛屿的数目
8690
1905. 统计子岛屿

leetcode_Java/Solution0583.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// 583. 两个字符串的删除操作
2+
3+
4+
class Solution {
5+
public int minDistance(String word1, String word2) {
6+
int n = word1.length(), m = word2.length();
7+
int[][] dp = new int[n + 1][m + 1];
8+
for (int i = 0; i <= n; i++) {
9+
dp[i][0] = i;
10+
}
11+
for (int j = 0; j <= m; j++) {
12+
dp[0][j] = j;
13+
}
14+
for (int i = 1; i <= n; i++) {
15+
for (int j = 1; j <= m; j++) {
16+
if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
17+
dp[i][j] = dp[i - 1][j - 1];
18+
} else {
19+
dp[i][j] = 1 + Math.min(dp[i - 1][j], dp[i][j - 1]);
20+
}
21+
}
22+
}
23+
return dp[n][m];
24+
}
25+
}

leetcode_Java/Solution0712.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// 712. 两个字符串的最小ASCII删除和
2+
3+
4+
class Solution {
5+
public int minimumDeleteSum(String s1, String s2) {
6+
int n = s1.length(), m = s2.length();
7+
int[][] dp = new int[n + 1][m + 1];
8+
for (int i = 1; i <= n; i++) {
9+
dp[i][0] = dp[i - 1][0] + s1.charAt(i - 1);
10+
}
11+
for (int j = 1; j <= m; j++) {
12+
dp[0][j] = dp[0][j - 1] + s2.charAt(j - 1);
13+
}
14+
for (int i = 1; i <= n; i++) {
15+
for (int j = 1; j <= m; j++) {
16+
if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
17+
dp[i][j] = dp[i - 1][j - 1];
18+
} else {
19+
dp[i][j] = Math.min(dp[i - 1][j] + s1.charAt(i - 1), dp[i][j - 1] + s2.charAt(j - 1));
20+
}
21+
}
22+
}
23+
return dp[n][m];
24+
}
25+
}

leetcode_Java/Solution0718.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// 718. 最长重复子数组
2+
3+
4+
class Solution {
5+
public int findLength(int[] nums1, int[] nums2) {
6+
int n = nums1.length, m = nums2.length;
7+
int res = 0;
8+
int[][] dp = new int[n + 1][m + 1];
9+
for (int i = 1; i <= n; i++) {
10+
for (int j = 1; j <= m; j++) {
11+
if (nums1[i - 1] == nums2[j - 1]) {
12+
dp[i][j] = dp[i - 1][j - 1] + 1;
13+
res = Math.max(res, dp[i][j]);
14+
} else {
15+
dp[i][j] = 0;
16+
}
17+
}
18+
}
19+
return res;
20+
}
21+
}
22+
23+
24+
/*
25+
如果是求“最长重复子序列”,即不要求连续,则解法如下。解法与“1143.最长公共子序列”相同
26+
*/
27+
class Solution {
28+
public int findLength(int[] nums1, int[] nums2) {
29+
int n = nums1.length, m = nums2.length;
30+
int[][] dp = new int[n + 1][m + 1];
31+
for (int i = 1; i <= n; i++) {
32+
for (int j = 1; j <= m; j++) {
33+
if (nums1[i - 1] == nums2[j - 1]) {
34+
dp[i][j] = dp[i - 1][j - 1] + 1;
35+
} else {
36+
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
37+
}
38+
}
39+
}
40+
return dp[n][m];
41+
}
42+
}

leetcode_Java/Solution1143.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// 1143. 最长公共子序列
2+
3+
4+
class Solution {
5+
public int longestCommonSubsequence(String text1, String text2) {
6+
int n = text1.length(), m = text2.length();
7+
int[][] dp = new int[n + 1][m + 1];
8+
for (int i = 1; i <= n; i++) {
9+
for (int j = 1; j <= m; j++) {
10+
if (text1.charAt(i - 1) == text2.charAt(j - 1)) {
11+
dp[i][j] = dp[i - 1][j - 1] + 1;
12+
} else {
13+
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
14+
}
15+
}
16+
}
17+
return dp[n][m];
18+
}
19+
}

0 commit comments

Comments
 (0)