题目描述
难度:Hard
相关话题:字符串
、动态规划
给定一个字符串S 和一个字符串T ,计算在 S 的子序列中 T 出现的个数。
一个字符串的一个子序列是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。(例如, "ACE"
是 "ABCDE"
的一个子序列,而 "AEC"
不是)
示例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
^^^
思路:
DP,dp[i][j]
表示[0,i]
区间的t
和[0,j]
区间的s
,之间有多少个独立子序列。
设置所有dp[0][i]
为true
,表示当t
为空字符串时,总是存在1个独立子序列。
当s[j-1]===t[i-1]
,那么dp[i][j]
就是除了当前相等的两个的序列数(dp[i-1][j-1]
)和上一个s
和当前j
能匹配的序列数(dp[i][j-1]
)。
方程为:dp[i][j]=dp[i-1][j-1]+dp[i][j-1]
当s[j-1]!==t[i-1]
,那么只需要将上一次s
与当前j
的匹配数赋值给当前dp[i][j]
。
方程为:dp[i][j]=dp[i][j-1]
/**
* @ Javascript中文网 - 前端进阶资源教程 https://www.javascriptc.com/
* @param {string} s
* @param {string} t
* @return {number}
*/
var numDistinct = function(s, t) {
let M=t.length, N=s.length
let dp=Array(M+1).fill().map(()=>Array(N+1).fill(0))
for(let i=0;i<N;i++){
dp[0][i]=1
}
for(let i=1;i<=M;i++){
for(let j=1;j<=N;j++){
let si=j-1,ti=i-1
if(s[si]===t[ti]){
dp[i][j]=dp[i-1][j-1]+dp[i][j-1]
}else{
dp[i][j]=dp[i][j-1]
}
}
}
return dp[M][N]
};
看完两件小事
如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:
- 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
- 关注公众号 「画漫画的程序员」,公众号后台回复「资源」 免费领取我精心整理的前端进阶资源教程
本文著作权归作者所有,如若转载,请注明出处
转载请注明:文章转载自「 Js中文网 · 前端进阶资源教程 」https://www.javascriptc.com