Distinct Subsequences

Total Accepted: 38466 Total Submissions: 143567My Submissions

Question Solution 

Given a string S and a string T, count the number of distinct subsequences of T in S.

A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, "ACE" is a subsequence of "ABCDE" while "AEC" is not).

Here is an example:
S = "rabbbit", T = "rabbit"

Return 3.

 
  首先要读懂题意。题目中“count the number of distinct subsequences of T in S.” sequence是序列的意思,subqequence就是子序列。我们知道序列是由一个个元素排列而成。所以,题目中的“字符串T”为“字符串S”的子序列。求“字符串S”中“子序列字符串T”的个数,也就变形为:取出“字符串S”中的若干元素,顺序排列,组成“字符串T”,有多少种取法?
  我认为上述分析思路比题目中提到的“删除元素”的思路要好。因为当T和S长度相近时,两种思路效率差不多;当S远大于T时,由于组成一次“字符串T”要删除非常多的元素,显然,效率远低于第一种思路。
 
  参考 Rachel Zhang 的解题报告,同样的,我具体用了两种不同的方法去解这个题。
 
  方法一:迭代+递归,具体思路是深度优先搜索(Depth First Search),但无法通过,因为TLE(Time Limit Exceeded)
  以字符串S=“PabZcdefSghZijZkSlmZnoPqrStuZvwSxZyZ” ,字符串T=“PSZ”为例。
  为了方便大家观察,我把'P'、'S'、'Z'在字符串S中的位置着重标出来。
  S中元素'P'的位置=0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
  S中元素'S'的位置=0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
  S中元素'Z'的位置=0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
  观察字符串。字符串中任意的元素'P'、'S'、'Z',如果以顺序排列,则组成满足条件的字符串S"PSZ"。
  那么我们如何保证在取'P'、'S'、'Z'的时候既是顺序排列,又不多取,不少取呢?
  显然,用DFS就可以做到。
  下面为不熟悉DFS的朋友具体讲个例子,高手可以直接跳过。
  Eg:
  先找字符串S中有几个'P',2个: 0, 23
  对位置为0的字符‘P’,其后面有几个'S',4个:8,16,25,31
  对位置为8的字符'S',其后面有几个'Z',6个:11,14,19,  28, 33, 35
  所以'0 8 11', '0 8 14 ', '0 8 19', '0 8 28', '0 8 28', '0 8 33', '0 8 35'都是subsequence“PSZ”。
  依次再遍历'0 16 X'、'0 25 X'的情况,依次类推。非常明显,这个例子就是“深度优先的”。
  以下是代码:
  1. class Solution(object):
  2. def numDistinct(self, s, t):
  3. """
  4. :type s: str
  5. :type t: str
  6. :rtype: int
  7. """
  8. num=[0]
  9. self.CountSubsequence(s,t,0,0,num)
  10. return num[0]
  11. def CountSubsequence(self,father_sequence,child_sequence,index_father,index_child,num):
  12. #print(index_father,index_child)
  13. len_father=len(father_sequence)
  14. len_child=len(child_sequence)
  15. if index_child==len_child:
  16. num[0]+=1
  17. #print("匹配到了相同的")
  18. else:
  19. #print("进入迭代")
  20. for i in range(index_father,len_father):
  21. if father_sequence[i]==child_sequence[index_child]:
  22. self.CountSubsequence(father_sequence,child_sequence,i+1,index_child+1,num)
  23. #这里num是一个列表,可以从外部访问的,所以不需要return

  方法二:DP(Dynamic Programming, 动态规划)

  此处参考陆草纯的解题报告将问题转化为“二维地图走法问题”。

  我觉得他在文章里对转化为“二维地图走法问题”说明的不清楚:

  疑问一:为何走的时候只能“对角线走”和“向右向下走”,不能“向下向右走”。

  疑问二:为何字符判断相等时,是“对角线走”和“向右向下走”相加;而字符不等时,只能“向右向下走”。

  经过自己的思考,我来说一下我的理解:

  一个子字符串t',一个父字符串s',两者一点一点相加。最终子字符串的长度加到T的长度,父字符串的长度加到S的长度。

  当字符不等时,也就是说,父字符串s‘中新加的元素s'[i]无法对走法有贡献,所以可以删掉,于是就变成了“向右向下走”

  字符相等时,父字符串s'中新加的元素s'[i]对走法有贡献,所以对角线是可以取的;同时“向右向下走”(即删掉s'[i])也是可行的;由于两者是不同的走法,自然要相加。

  显然,DP的思路是从0开始一点一点增加子字符串的长度,最终达到我们想要匹配的字符串长度。显然不能减少字符串t'的长度。

  大家画个图就明白了,以s' 为纵轴,t'为横轴。下面直接上AC的python代码:

  

  1. class Solution(object):
  2. def numDistinct(self, s, t):
  3. """
  4. :type s: str
  5. :type t: str
  6. :rtype: int
  7. """
  8. #s is father_sequence
  9. #t is child_sequence
  10. len_father=len(s)
  11. len_child=len(t)
  12. dp=[[0 for i in range(len_child)] for j in range(len_father)]
  13. if len_father==0 or len_child==0:
  14. result=0
  15. else:
  16. #dp=[[0 for i in range(len_child)] for j in range(len_father)]
  17. if s[0]==t[0]:
  18. dp[0][0]=1
  19. for i in range(1,len_father):
  20. dp[i][0]=dp[i-1][0]
  21. if s[i]==t[0]:
  22. dp[i][0]+=1
  23.  
  24. for i in range(1,len_father):
  25. for j in range(1,len_child):
  26. if i>=j:
  27. if s[i]==t[j]:
  28. dp[i][j]=dp[i-1][j-1]+dp[i-1][j]
  29. else:
  30. dp[i][j]=dp[i-1][j]
  31. result=dp[len_father-1][len_child-1]
  32. return result

Leetcode 115 Distinct Subsequences 解题报告的更多相关文章

  1. 【LeetCode】115. Distinct Subsequences 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 动态规划 日期 题目地址:https://leetc ...

  2. LeetCode: Distinct Subsequences 解题报告

    Distinct Subsequences Given a string S and a string T, count the number of distinct subsequences of  ...

  3. Java for LeetCode 115 Distinct Subsequences【HARD】

    Given a string S and a string T, count the number of distinct subsequences of T in S. A subsequence ...

  4. [LeetCode] 115. Distinct Subsequences 不同的子序列

    Given a string S and a string T, count the number of distinct subsequences of S which equals T. A su ...

  5. leetcode 115 Distinct Subsequences ----- java

    Given a string S and a string T, count the number of distinct subsequences of T in S. A subsequence ...

  6. [leetcode]115. Distinct Subsequences 计算不同子序列个数

    Given a string S and a string T, count the number of distinct subsequences of S which equals T. A su ...

  7. Leetcode#115 Distinct Subsequences

    原题地址 转化为求非重路径数问题,用动态规划求解,这种方法还挺常见的 举个例子,S="aabb",T="ab".构造如下地图("."表示空位 ...

  8. 【LeetCode】792. Number of Matching Subsequences 解题报告(Python)

    [LeetCode]792. Number of Matching Subsequences 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://f ...

  9. 【LeetCode】659. Split Array into Consecutive Subsequences 解题报告(Python)

    [LeetCode]659. Split Array into Consecutive Subsequences 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id ...

随机推荐

  1. 洛谷 P3313 [SDOI2014]旅行

    题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰. 为了方便,我 ...

  2. db2新添用户

    --1.新添用户  -目录 /XX/XX  -组  XX 用户名useradd -d /home/xx -g users xx--2.修改密码passwd xx--3.在QC中grant权限.新添表空 ...

  3. Leetcode重点 250题-前400 题

    删除不常考,面试低频出现题目 删除重复代码题目(例:链表反转206题,代码在234题出现过) 删除过于简单题目(例:100题:Same Tree) 删除题意不同,代码基本相同题目(例:136 & ...

  4. Bootstrap 提示工具(Tooltip)插件

    当您想要描述一个链接的时候,使用提示工具插件是一个不错的选择.Bootstrap提示工具插件做了很多的改进,例如不需要依赖图像,而是改变Css动画效果,用data属性来存储标题信息. 用法 提示工具( ...

  5. 01_4_Struts路径问题

    01_4_Struts路径问题 1. Struts路径问题说明 struts2中的路径问题是根据action的路径而不是jsp路径来确定,所有尽量不要使用相对路径. 虽然可以使用redirect方式解 ...

  6. CentOS7系统引导顺序以及排障

    引导顺序 UEFi或BIOS初始化,运行POST开机自检 选择启动设备 引导装载程序, centos7是grub2 加载装载程序的配置文件:/etc/grub.d/  /etc/default/gru ...

  7. 理解JWT的使用场景和优劣

    理解JWT的使用场景和优劣 淘楼小能手 百家号04-2816:20 经过前面两篇文章<JSON Web Token - 在Web应用间安全地传递信息><八幅漫画理解使用JSON We ...

  8. (66)zabbix导入/导出配置文件

    通过导入/导出zabbix配置文件,我们可以将自己写好的模板等配置在网络上分享,我们也可以导入网络上分享的配置文件 配置文件有两种格式,分为为xml与json,通过zabbix管理界面可以导出xml, ...

  9. NodeJS基础入门-Buffer

    Buffer.byteLength console.log(Buffer.byteLength('test')); console.log(Buffer.byteLength('我是C语言爱好者')) ...

  10. october安装过程

    下载代码 composer create-project october/october myoctober 准备好数据库, create database october; 配置环境于安装 php ...