1.题目
给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。
一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。
例如,“ace” 是 “abcde” 的子序列,但 “aec” 不是 “abcde” 的子序列。
两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。
示例1:
输入:text1 = “abcde”, text2 = “ace”
输出:3
解释:最长公共子序列是 “ace” ,它的长度为 3 。
示例2:
输入:text1 = “abc”, text2 = “def”
输出:0
解释:两个字符串没有公共子序列,返回 0 。
2.思路分析
求公共子序列或者连续子序列,我们可以使用动态规划算法的思路来做,因为这个问题可以划分为相似的子问题,且大问题依赖于子问题。
2.1状态:
F(i , j) : 代表字符串1的前i个字符和字符串2的前j个字符的最长公共子串
2.2状态转移方程:
判断字符串1第i个字符与字符串2的第j个字符是否相等
如果相等:F(i,j)= F(i-1,j-1)+1
如果不相等:F(i, j) = Math.max{ F(i-1, j), F(i, j - 1)}
2.3初始化:
i = 0时,F(0 , j) = 0
j = 0时,F(i ,0) = 0
2.4返回值
F(str1.length() , str.length() )
3.代码
package test2;
public class Test03 {
public static void main(String[] args) {
System.out.println(longestCommonSubsequence("abcde","ace"));
}
public static int longestCommonSubsequence(String text1, String text2){
char [] arr1 = text1.toCharArray();
char [] arr2 = text2.toCharArray();
//定义一个二维数组
int [][] array = new int [arr1.length+1][arr2.length+1];
for(int i = 0; i < arr1.length; i++){
for(int j = 0; j < arr2.length; j++){
//如果相等
if(arr1[i] == arr2[j]){
array[i+1][j+1] = array[i][j]+1;
}else{
//不相等时
array[i+1][j+1] = Math.max(array[i+1][j],array[i][j+1]);
}
}
}
return array[arr1.length][arr2.length];
}
}
4.总结
动态规划具备了以下三个特点
- 把原来的问题分解成了几个相似的子问题。
- 所有的子问题都只需要解决一次。
- 储存子问题的解。
本文通过一个具体的例子详细介绍了如何使用动态规划算法解决最长公共子序列问题。通过定义状态转移方程,初始化边界条件,并给出具体代码实现,展示了动态规划在解决字符串匹配问题中的应用。最后,总结了动态规划的特点和该问题的解决方案。

被折叠的 条评论
为什么被折叠?



