-
给你两个字符串 s 和 t ,统计并返回在 s 的 子序列 中 t 出现的个数。
-
题目数据保证答案符合 32 位带符号整数范围。
示例 1:
输入:s = "rabbbit", t = "rabbit"
输出:3
解释:
如下所示, 有 3 种可以从 s 中得到 "rabbit" 的方案。
rabbbit
rabbbit
rabbbit
示例 2:
输入:s = "babgbag", t = "bag"
输出:5
解释:
如下所示, 有 5 种可以从 s 中得到 "bag" 的方案。
babgbag
babgbag
babgbag
babgbag
babgbag
提示:
1 <= s.length, t.length <= 1000
s 和 t 由英文字母组成
通过次数142,243提交次数272,458
code
- 用记忆化搜索(记忆化递归)解决字符串匹配问题这段代码是一个动态规划算法求解字符串匹配问题的实现。其中,使用了记忆化搜索的思想,即在搜索过程中利用哈希表存储已经搜索过的位置的结果,避免重复计算。具体实现中,使用一个哈希表
mp存储已经搜索过的位置的结果,键为(i, j),表示在字符串s中从位置i开始和字符串t中从位置j开始进行匹配的结果,值为匹配的方案数。在搜索的过程中,如果当前位置(i, j)已经被搜索过,直接返回哈希表中存储的结果;如果字符串t已经匹配完了,说明找到了一种匹配方案,返回 1;如果字符串s已经匹配完了但是字符串t还没有匹配完,说明没有匹配方案,返回 0。在搜索的过程中,对于每个位置(i, j),可以选择跳过s[i],并进行下一步搜索:s[i+1]与t[j]匹配,或者选择s[i],并进行下一步搜索:s[i]与t[j+1]匹配。如果s[i]和t[j]相等,可以选择s[i],并进行下一步搜索:s[i+1]与t[j+1]匹配。最终返回从s[0]和t[0]开始匹配的方案数。
class Solution {
public:
map<pair<int,int>,int> mymap;
int dfs_memory(string &s, string &t,int i, int j){
if( mymap.count({i,j})!=0)
return mymap[{i,j}];
if(j==t.size())
return 1;// t匹配完了
if(i==s.size())
return 0;// s匹配完了依然没找到答案
int cnt=0;
//不选择s[i]
cnt+=dfs_memory(s,t,i+1,j);
//选择s[i]
if(s[i]==t[j])
cnt+=dfs_memory(s,t,i+1,j+1);
// cout<< i << j <<endl; //可看下赋值的情况,提交时加上这个输出会超时
mymap[{i,j}]=cnt;
return cnt;
}
int numDistinct(string s, string t) {
return dfs_memory(s,t,0,0);
}
};
CG
class Solution:
def numDistinct(self, s: str, t: str) -> int:
mp = {} # 记忆化单元【哈希表存储】
# @functools.cache
def dfs(i, j):
if (i, j) in mp: # 以前搜索过该位置
return mp[(i,j)]
if j == len(t): # t匹配完了
return 1
if i == len(s): # s匹配完了依然没找到答案
return 0
cnt = 0
# 跳过s[i],并进行下一步搜索:s[i+1]与t[j]匹配
cnt += dfs(i+1, j)
# 选择s[i],并进行下一步搜索
if s[i] == t[j]: # 能选择s[i]的前提条件为:s[i] == t[j]
cnt += dfs(i+1, j+1)
mp[(i, j)] = cnt # 记录下 (i,j) 的结果,以备后续直接使用
return cnt
return dfs(0, 0) # 初始从s[0]和t[0]开始搜索
文章介绍了如何使用动态规划和记忆化搜索解决字符串子序列匹配问题。给定两个字符串s和t,目标是计算s中有多少个子序列与t相同。通过递归函数dfs_memory,利用记忆化技术存储已计算过的状态,避免重复计算,从而提高效率。在匹配过程中,考虑是否选择当前字符或跳过,根据字符是否相等决定下一步搜索路径。

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



