子字符串匹配
给定两个字符串s和t,其中t是s的子字符串,s的子字符串是字符串都取自s,并且保持在s的位置的相对顺序,但不需要是连续的。比如,s="abcdef", t="bd"
要求找出t在s中匹配的字符串数量
Input: s="rabbbit" t="rabbit"
Output:3
题解
这道题类似于求最长公共子序列(lcs)
类似:不需要连续,只需要相对顺序相同
不同:
lcs是子序列不确定,找相同序列的最长长度;
此题是子序列已定,母串必须包括字串的全部,问的是个数
lcs
/**
* dp[i][j]代表母串的前i个字符和子串前j个字符匹配最长长度
*/
for(int i = 1; i <= len1; i++)
{
for(int j = 1; j <= len2; j++)
{
if(s1[i] == s2[j]) {
dp[i][j] = dp[i - 1][j - 1] + 1;//一定是这最后一个字母来作为公共子序列的结尾
}
else {
dp[i][j] = max(dp[i][j - 1],dp[i - 1][j]);//一定不是它做结尾,则看之前的情况谁长谁上
}
}
}
public int numberOfString(String S, String T) {
/**
* dp[i][j]
* T前i个字符的子序列在母串S前i个字符中出现的次数
*/
int maxx = 1000;
int[][] dp = new int[maxx][maxx];
for (int i = 0; i < maxx; i++) {
for (int j = 0; j < maxx; j++) {
dp[i][j] = 0;
dp[0][j] = 1; //子串长度为0 只出现一次
}
}
int len1 = T.length();
int len2 = S.length();
for (int i = 1; i <= len1; i++) {
for (int j = 1; j <= len2; j++) {
if (T.charAt(i - 1) != S.charAt(j - 1)) {
dp[i][j] = dp[i][j - 1];
} else {
dp[i][j] = dp[i][j - 1] + dp[i - 1][j - 1];
}
}
}
return dp[len1][len2];
}