判断子序列 LeetCode 392
题目链接:[LeetCode 392 - 简单]
思路
本来打算使用boolean数组作为dp数组,但是校验比较难。 还是使用int数组更为保险且代码容易写。
动态规划:
class Solution {
public boolean isSubsequence(String s, String t) {
int len1=s.length();
int len2=t.length();
int[][] dp = new int[len1+1][len2+1];
for(int i=1;i<=len1;i++){
for(int j=1;j<=len2;j++){
if(s.charAt(i-1)==t.charAt(j-1)){
dp[i][j]=dp[i-1][j-1]+1;
}else{
dp[i][j]=dp[i][j-1];
}
}
}
if(dp[len1][len2]==len1){
return true;
}else{
return false;
}
}
}
不同的子序列 LeetCode 155
题目链接:[LeetCode 155 - 困难]
思路
动态规划:
class Solution {
public int numDistinct(String s, String t) {
int len1 = s.length();
int len2 = t.length();
int[][] dp = new int[len1+1][len2+1];
for(int i=0;i<=len1;i++){
dp[i][0]=1;
}
for(int i=1;i<=len1;i++){
for(int j=1;j<=len2;j++){
if(s.charAt(i-1)==t.charAt(j-1)){
dp[i][j]=dp[i-1][j-1]+dp[i-1][j];
}else{
dp[i][j]=dp[i-1][j];
}
}
}
return dp[len1][len2];
}
}
两个字符串的删除操作 LeetCode 583
题目链接:[LeetCode 583 - 中等]
思路
大部分的内容能够想到
但是递推公式:dp[i][j]=dp[i-1][j-1]+1和dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]);
动态规划:
class Solution {
public int minDistance(String word1, String word2) {
int[][] dp = new int[word1.length()+1][word2.length()+1];
for(int i=1;i<=word1.length();i++){
for(int j=1;j<=word2.length();j++){
if(word1.charAt(i-1)==word2.charAt(j-1)){
dp[i][j]=dp[i-1][j-1]+1;
}else{
dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]);
}
}
}
return word1.length()+word2.length()-2*dp[word1.length()][word2.length()];
}
}
编辑距离 LeetCode 72
题目链接:[LeetCode 72 - 中等]
思路
动态规划五部曲:
①确认dp数组和下标:
下标为i-1的word1和下标为j-1的word2之间的距离
②递推公式:
word1[i - 1] == word2[j - 1]:dp[i][j]=dp[i-1][j-1];
word1[i - 1] != word2[j - 1]:dp[i][j]=Math.min(Math.min(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1])+1;
③初始化数组:
dp[i][0]就应该是i,对word1里的元素全部做删除操作,即:dp[i][0] = i; dp[0][j]同理
④遍历顺序: 一定是从左到右从上到下去遍历
动态规划:
class Solution {
public int minDistance(String word1, String word2) {
int[][] dp = new int[word1.length()+1][word2.length()+1];
for(int i=0;i<=word1.length();i++){
dp[i][0]=i;
}
for(int j=0;j<=word2.length();j++){
dp[0][j]=j;
}
for(int i=1;i<=word1.length();i++){
for(int j=1;j<=word2.length();j++){
if(word1.charAt(i-1)==word2.charAt(j-1)){
dp[i][j]=dp[i-1][j-1];
}else{
dp[i][j]=Math.min(Math.min(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1])+1;
}
}
}
return dp[word1.length()][word2.length()];
}
}