LeetCode392. 判断子序列
题目链接:392. 判断子序列
思路
-
第一步,确定dp数组以及其下标的含义
dp
数组表示以i- 1
结尾的字符串s
,和以j - 1
结尾的字符串t
, 相同子序列的长度。
-
第二步,确定递推公式(考虑两种情况)
-
情况一:
chs[i - 1] == cht[j - 1]
时,此时相同子序列的长度为
d p [ i ] [ j ] = d p [ i − 1 ] [ j − 1 ] + 1 dp[i][j] = dp[i - 1][j - 1] + 1 dp[i][j]=dp[i−1][j−1]+1 -
情况二:
chs[i - 1] != cht[j - 1]
时,此时相同子序列的长度为
d p [ i ] [ j ] = d p [ i ] [ j − 1 ] dp[i][j] = dp[i][j - 1] dp[i][j]=dp[i][j−1]
-
-
第三步,初始化
- 通过对递推公式的观察,需要初始化
dp[i][0]
和dp[0][j]
。其表示s
为空或者t
为空时,相同子序列的长度,所以dp[i][0] == 0
,dp[0][j] == 0
。
- 通过对递推公式的观察,需要初始化
-
第四步,遍历顺序
dp[i][j]
的值都是依赖于dp[i - 1][j - 1]
和dp[i][j - 1]
,所以,遍历顺序是从上往下,从左往右。
代码
class Solution {
public boolean isSubsequence(String s, String t) {
int lens = s.length();
int lent = t.length();
char[] chs = s.toCharArray();
char[] cht = t.toCharArray();
int[][] dp = new int[lens + 1][lent + 1];
for (int i = 1; i < lens + 1; i++){
for (int j = 1; j < lent + 1; j++){
if (chs[i - 1] == cht[j - 1]){
dp[i][j] = dp[i - 1][j - 1] + 1;
}else {
dp[i][j] = dp[i][j - 1];
}
}
}
if (dp[lens][lent] == lens){
return true;
}
return false;
}
}
LeetCode115.不同子序列
题目链接:115.不同子序列
思路
-
第一步,确定dp数组以及其下标的含义
dp[i][j]
表示以i- 1
结尾的s
子序列出现以j - 1
结尾的t
的个数。
-
第二步,确定递推公式(分两种情况考虑)
-
情况一:
chs[i - 1] == cht[j - 1]
,此时dp[i][j]
由两部分组成,即dp[i - 1][j - 1]
和dp[i - 1][j]
。其中dp[i - 1][j - 1]
容易理解,表示不考虑当前字符串s
和字符串t
最后一位字符。dp[i - 1][j]
表示采用chs[i - 1]
进行匹配。
d p [ i ] [ j ] = d p [ i − 1 ] [ j − 1 ] + d p [ i − 1 ] [ j ] dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j] dp[i][j]=dp[i−1][j−1]+dp[i−1][j] -
情况二:
chs[i - 1] != cht[j - 1]
,此时不采用当前字符串s
的最后一位字符匹配。
d p [ i ] [ j ] = d p [ i − 1 ] [ j ] dp[i][j] = dp[i - 1][j] dp[i][j]=dp[i−1][j]
-
-
第三步,初始化
- 从递推公式可以得出,需要初始化
dp[i][0]
和dp[0][j]
。dp[i][0]
表示以i- 1
结尾的字符串s
中出现空字符串的个数。dp[0][j]
表示空字符串,出现以j - 1
结尾的字符串t
的个数。 - 所以,
dp[i][0] == 1
,dp[0][j]== 0
,其中,特殊的dp[0][0] == 1
。
- 从递推公式可以得出,需要初始化
-
第四步,遍历顺序
- 从递推公式得出,遍历顺序应该从上往下,从左往右。
代码:
class Solution {
public int numDistinct(String s, String t) {
char[] chs = s.toCharArray();
char[] cht = t.toCharArray();
int[][] dp = new int[chs.length + 1][cht.length + 1];
for (int i = 0; i < chs.length; i++){
dp[i][0] = 1;
}
for (int j = 1;j < cht.length; j++){
dp[0][j] = 0;
}
for (int i = 1; i < chs.length + 1; i++){
for (int j = 1; j < cht.length + 1; j++){
if (chs[i - 1] == cht[j - 1]){
dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
}else {
dp[i][j] = dp[i - 1][j];
}
}
}
return dp[chs.length][cht.length];
}
}