LeetCode 392 判断子序列
题目链接:392. 判断子序列 - 力扣(LeetCode)
【解题思路】
-
1.确定dp数组含义
-
dp[i][j]:表示以下标i-1为结尾的字符串s,和以下标j-1为结尾的字符串t,相同子序列的长度为dp[i][j]
-
-
2.确定递推公式
-
s[i-1] == t[j-1]
-
意思是找到了一个相同的字符
-
dp[i][j] = dp[i-1][j-1]+1
-
-
s[i-1] != t[j-1]
-
意思是当前位置的两个字符串的字符不相同此时相当于t要删除元素
-
dp[i][j] = dp[i][j-1]
-
-
-
3.初始化dp数组
-
从递推公式可以看出dp[i][j]都是依赖于dp[i-1][j-1]推出来,因此需要初始化dp[0][0],dp[i][0]
-
将他们都初始化为0
-
-
-
4.确定遍历顺序
-
由递推公式可以知道,遍历顺序一定是从上到下,从左到右
-
-
5.举例推导dp数组
【解题步骤】
-
1.定义两个变量存储题目给出的两个字符串长度,方便后续操作
-
2.定义一个dp数组,长度为两个字符串的长度+1
-
3.遍历字符串1,从1开始
-
遍历字符串2,从2开始
-
递推公式
-
-
-
4.判断dp[length1][length2]的长度
-
如果等于length1
-
说明是子序列,return true
-
-
如果不等于length2
-
说明不是子序列,return false
-
-
【代码部分】
class Solution {
public boolean isSubsequence(String s, String t) {
int length1 = s.length();
int length2 = t.length();
int[][] dp = new int[length1+1][length2+1];
for (int i = 1; i <= length1; i++) {
for (int j = 1; j <= length2; 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[length1][length2] == length1){
return true;
}else{
return false;
}
}
}
LeetCode 115 不同的子序列
题目链接:115. 不同的子序列 - 力扣(LeetCode)
【解题思路】
-
1.确定dp数组含义
-
dp[i][j]:表示以下标i-1为结尾的子序列s中出现以j-1为结尾的t的个数为dp[i][j]
-
-
2.确定递推公式
-
s[i-1] == t[j-1]
-
用s[i-1]来匹配
-
dp[i][j] = dp[i-1][dp[j-1]
-
-
不用s[i-1]来匹配
-
dp[i-1][j]
-
-
-
s[i-1] != t[j-1]
-
此时不能用s[i-1]来匹配,模拟在s中删除这个元素
-
dp[i][j] = dp[i-1][j]
-
-
-
3.初始化dp数组
-
从递推公式可以看出dp[i][j]都是依赖于dp[i-1][j-1]推出来,因此需要初始化dp[0][j],dp[i][0]
-
dp[i][0]
-
以i-1为结尾的s可以随便删除元素,出现空字符串的个数
-
dp[i][0] = 1
-
也就是把以i-1为结尾的s,删除所有元素,出现空字符串的个数就是1
-
-
-
dp[0][j]
-
空字符串s可以随便删除元素,出现以j-1为结尾的字符串t的个数
-
dp[0][j] = 0
-
s无论如何也变成不了t
-
-
-
dp[0][0]
-
dp[0][0] = 1
-
空字符串s,可以删除0个元素,变成空字符串t
-
-
-
-
-
4.确定遍历顺序
-
由递推公式可以知道,遍历顺序一定是从上到下,从左到右
-
-
5.举例推导dp数组
【解题步骤】
-
1.定义一个dp数组,长度为两个字符串的长度+1
-
3.遍历字符串s
-
将dp[i][0]初始化为1
-
-
4.遍历字符串s
-
遍历字符串t
-
如果两个字符串当前位置的元素相同
-
递推公式1
-
-
如果两个字符串当前位置的元素不同
-
递推公式2
-
-
-
-
5.return dp[s.length()][t.length()]
【代码部分】
class Solution {
public int numDistinct(String s, String t) {
int[][] dp = new int[s.length()+1][t.length()+1];
for (int i = 0; i < s.length() + 1; i++) {
dp[i][0] = 1;
}
for (int i = 1; i < s.length() +1; i++) {
for (int j = 1; j < t.length()+1; 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[s.length()][t.length()];
}
}