【python】Leetcode每日一题-不同的子序列
【python】Leetcode每日一题-不同的子序列
【题目描述】
给定一个字符串 s 和一个字符串 t ,计算在 s 的子序列中 t 出现的个数。
字符串的一个 子序列 是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。(例如,"ACE" 是 "ABCDE" 的一个子序列,而 "AEC" 不是)
题目数据保证答案符合 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
^^^
提示:
0 <= s.length, t.length <= 1000
s 和 t 由英文字母组成
【分析】
【超时】思路:
自己原先思路是对
s和t顺序匹配,使用dfs遍历,最后时间超时,分析时间复杂度,代码模型为\(O(m^n)\),当然比这个小很多,并不是完整的树结构。代码:
class Solution(object):
s = ""
t = ""
num = 0
def numDistinct(self, s, t):
"""
:type s: str
:type t: str
:rtype: int
"""
self.s = s
self.t = t
self.dfs(0, 0)
return self.num def dfs(self, s_index, t_index):
if(t_index == len(self.t)):
self.num += 1
return
for x in range(len(self.s)-s_index):
if(self.s[x+s_index] == self.t[t_index]):
self.dfs(x+s_index+1, t_index+1)
【dp】思路:
dp[i][j]表示s[0...i]、t[0...j]之间的子序列数。提供dp转移方程:
\[\begin{cases}
dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];&s[i] == t[j]\\
dp[i][j] = dp[i - 1][j];&s[i] != t[j]
\end{cases}
\]- 解释:当
s[i] == t[j]时,dp[i][j]可分为s串尾部是否形成匹配两种情况,如果在与t匹配中形成匹配了,则为子序列为dp[i-1][j-1],即除开s、t两串最后一个字母的子序列数,如果未形成匹配,则为dp[i-1][j],即s、t两串不包含s串最后一个字母的子序列数。 - 时间复杂度:\(O(mn)\)
AC代码:
class Solution(object):
def numDistinct(self, s, t):
"""
:type s: str
:type t: str
:rtype: int
"""
m = len(s)
n = len(t)
dp = [[0]*(n+1) for i in range(m+1)]
for i in range(m+1):
dp[i][0] = 1
for i in range(1, m+1):
for j in range(1, n+1):
if(j > i):
continue
if(s[i-1] == t[j-1]):
dp[i][j] = dp[i-1][j-1] + dp[i-1][j]
else:
dp[i][j] = dp[i-1][j]
return dp[m][n]
讨论:
看到一位兄弟的评论,图一乐
去的超时!不过63个测试用例而已,大不了我写63个case
public class Solution {
public int NumDistinct(string s, string t) {
switch(t){
case "bddabdcae":return 10582116;
case "bcddceeeebecbc":return 700531452;
case "ccdeddeabb":return 527764581;
case "baaacbceabba":return 1293119;
case "aeacbde":return 2543265;
case "rwmimatmhydhbujebqehjprrwfkoebcxxqfktayaaeheys":return 543744000;
case "rwmimatmhydhbujebqehjprarwfkoebcxxqfktayaaeheys":return 1456742400;
default:return fun(s,t,0,0);
}
}
private int fun(string s,string t,int i,int j){
int res=0;
for(;i<s.Length&&j<t.Length;i++){
if(s[i]==t[j]){
res+=fun(s,t,i+1,j);
j++;
}
}
if(j<t.Length)return 0;
return res+1;
}
}
看了官方题解,意识到动态规划边界条件的确也很重要:
当
j=n时,t[j:]为空字符串,由于空字符串是任何字符串的子序列,因此对任意 \(0 \le i \le m\),有 \(\textit{dp}[i][n]=1\);当
i=m且j<n时,s[i:]为空字符串,t[j:]为非空字符串,由于非空字符串不是空字符串的子序列,因此对任意 \(0 \le j<n\),有 \(\textit{dp}[m][j]=0\)。
官方题解: 戳这里
【python】Leetcode每日一题-不同的子序列的更多相关文章
- 【python】Leetcode每日一题-最长公共子序列
[python]Leetcode每日一题-最长公共子序列 [题目描述] 给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度.如果不存在 公共子序列 ,返回 0 . ...
- 【python】Leetcode每日一题-132模式
[python]Leetcode每日一题-132模式 [题目描述] 给定一个整数序列:a1, a2, ..., an,一个132模式的子序列 ai, aj, ak 被定义为:当 i < j &l ...
- 【python】Leetcode每日一题-寻找旋转排序数组中的最小元素
[python]Leetcode每日一题-寻找旋转排序数组中的最小元素 [题目描述] 已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组.例如,原数组nums ...
- 【python】Leetcode每日一题-删除有序数组中的重复项
[python]Leetcode每日一题-删除有序数组中的重复项 [题目描述] 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现一次 ,返回删除后数组的新长度. 不要 ...
- 【python】Leetcode每日一题-存在重复元素3
[python]Leetcode每日一题-存在重复元素3 [题目描述] 给你一个整数数组 nums 和两个整数 k 和 t .请你判断是否存在 两个不同下标 i 和 j,使得 abs(nums[i] ...
- 【python】Leetcode每日一题-扰乱字符串
[python]Leetcode每日一题-扰乱字符串 [题目描述] 使用下面描述的算法可以扰乱字符串 s 得到字符串 t : 如果字符串的长度为 1 ,算法停止 如果字符串的长度 > 1 ,执行 ...
- 【python】Leetcode每日一题-前缀树(Trie)
[python]Leetcode每日一题-前缀树(Trie) [题目描述] Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的 ...
- 【python】Leetcode每日一题-打家劫舍2
[python]Leetcode每日一题-打家劫舍2 [题目描述] 你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金.这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋 ...
- 【python】Leetcode每日一题-二叉搜索树节点最小距离
[python]Leetcode每日一题-二叉搜索树节点最小距离 [题目描述] 给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 . 示例1: 输入:root = [4 ...
随机推荐
- JAVA_标识符、数据类型、变量
标识符和关键字 所有的标识符否应该以字母a ~ z和 A ~Z ,美元符($).下划线(_)开始. 首字符之后可以是字母a ~ z和 A ~Z ,美元符($).下划线(_)的任意字符组合. 注 ...
- FreeBSD 中文TTY控制台
freebsd新型终端VT,支持cjk,所以丢个字体进去,就能显示中文了1,首先你没有改过控制台程序,使用的是默认的,,2,最新版本,本说明是以freebsd12.1release字体格式为.fnt命 ...
- POJ_2828 Buy Tickets 【线段树】
一.题目 Buy Tickets 二.分析 首先可以明确的是每个人的位置都是定的,那么如果从输入数据从后往前看,最后面的人进来的时候,他前面的人数肯定是定的. 那么可以考虑,当从后往前推时,这个人插入 ...
- Python-sendgrid邮箱库的使用
Python中sendgrid库使用 #帮助文档https://github.com/sendgrid/sendgrid-python https://sendgrid.com/docs/ui/acc ...
- C# 通过ServiceStack 操作Redis——List类型的使用及示例
Redis list的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销, /// <summary> /// Redis list的实现为一个双向链表 ...
- CSS-clear属性的作用
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="U ...
- P1200_你的飞碟在这儿(JAVA语言)
题目描述 众所周知,在每一个彗星后都有一只UFO.这些UFO时常来收集地球上的忠诚支持者. 不幸的是,他们的飞碟每次出行都只能带上一组支持者.因此,他们要用一种聪明的方案让这些小组提前知道谁会被彗星带 ...
- Vulkan移植GpuImage(二)Harris角点检测与导向滤波
Harris角点检测 UI还是用的上次扣像的,只有前后置可以用,别的没有效果,只看实现就好. 相应源码 在实现之前,我先重新整理编译glsl的生成工具,如Harris角点检测中间计算过程需要针对rgb ...
- SpringBoot-02 运行原理初探
SpringBoot-02 运行原理初探 本篇文章根据b站狂神编写 pom.xml 2.1.父依赖 其中它主要是依赖一个父项目,主要是管理项目的资源过滤及插件! <parent> < ...
- 第20 章 : GPU 管理和 Device Plugin 工作机制
GPU 管理和 Device Plugin 工作机制 本文将主要分享以下几个方面的内容: 需求来源 GPU 的容器化 Kubernetes 的 GPU 管理 工作原理 课后思考与实践 需求来源 201 ...