动态规划-字符串

  1. 两字符串的最长公共字符串
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public static void main(String[] args) {
String str1="ABC12345E98765432kjask";
String str2="p1234e598765432ahnxvm";
int m=str1.length();
int n=str2.length();
int start=0;
int end=0;
int maxlen=0;
int[][] dp=new int[m+1][n+1];//str1的i到str2的j的最长公共字符串
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(str1.charAt(i-1)==str2.charAt(j-1)){
dp[i][j]=dp[i-1][j-1]+1;
if(dp[i][j]>maxlen){
maxlen=dp[i][j];
start=i-maxlen;
end=i;
}
}
}
}
System.out.println(str1.substring(start,end));
}
  1. 两字符串的最长公共序列长度
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static void main(String[] args) {
//最长公共子序列长度
String str1="abc98759847j374s34897o38i";
String str2="bc&&&&&&&4&&&&&o3****8))";
int m=str1.length();
int n=str2.length();
int[][] dp=new int[m+1][n+1];
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(str1.charAt(i-1)==str2.charAt(j-1)){
dp[i][j]=dp[i-1][j-1]+1;
}else{
dp[i][j]=Math.max(dp[i][j-1],dp[i-1][j]);
}
}
}
System.out.println(dp[m][n]);
}
  1. 两字符串的删除操作(就是两字符串的公共序列变形)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static void main(String[] args) {
//最长公共子序列长度
String str1="set";
String str2="eat";
int m=str1.length();
int n=str2.length();
int[][] dp=new int[m+1][n+1];
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(str1.charAt(i-1)==str2.charAt(j-1)){
dp[i][j]=dp[i-1][j-1]+1;
}else{
dp[i][j]=Math.max(dp[i][j-1],dp[i-1][j]);
}
}
}
System.out.println(m+n-2*dp[m][n]);
}
  1. 编辑距离
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public int minDistance(String word1, String word2) {
int m=word1.length();
int n=word2.length();
int[][] dp=new int[m+1][n+1];
for(int i=1;i<=m;i++){
dp[i][0]=dp[i-1][0]+1;
}
for(int i=1;i<=n;i++){
dp[0][i]=dp[0][i-1]+1;
}
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(word1.charAt(i-1)==word2.charAt(j-1)){
dp[i][j]=dp[i-1][j-1];
}else{
dp[i][j]=Math.min(dp[i][j-1],Math.min(dp[i-1][j],dp[i-1][j-1]))+1;
}
}
}
return dp[m][n];
}
  1. 阿里笔试题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 求多个字符串能构成的有序的最长长度(题目描述不准确)
* 比如abc efg zzz efghi
* 答案应该是abcefghizzz 长度是11
*/
public static int music(String[] s){
Arrays.sort(s);
int count = s[0].length();
int dp[] = new int[s.length]; //dp数组为包含当前字符串的最大长度
dp[0] = s[0].length();
for (int i = 1; i < s.length; i++) {
int j = s[i].length();
char x = s[i].charAt(0);
for (int k = 0; k < i; k++) {
char y = s[k].charAt(s[k].length() - 1);
if(x >= y){ //判断是否可以连接
j = Math.max(dp[k] + s[i].length(), j); //寻找可以连接的最大长度
}
}
dp[i] = j;
count = Math.max(count,j);
}
return count;
}