1. 首页

LeetCode 115. 不同的子序列

题目描述

难度: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]
};

看完两件小事

如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:

  1. 关注我们的 GitHub 博客,让我们成为长期关系
  2. 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
  3. 关注公众号 「画漫画的程序员」,公众号后台回复「资源」 免费领取我精心整理的前端进阶资源教程

JS中文网是中国领先的新一代开发者社区和专业的技术媒体,一个帮助开发者成长的社区,目前已经覆盖和服务了超过 300 万开发者,你每天都可以在这里找到技术世界的头条内容。欢迎热爱技术的你一起加入交流与学习,JS中文网的使命是帮助开发者用代码改变世界

本文著作权归作者所有,如若转载,请注明出处

转载请注明:文章转载自「 Js中文网 · 前端进阶资源教程 」https://www.javascriptc.com

标题:LeetCode 115. 不同的子序列

链接:https://www.javascriptc.com/4478.html

« 京东小程序开放平台终于来了~
LeetCode 114. 二叉树展开为链表»
Flutter 中文教程资源

相关推荐

QR code