Skip to content

Commit a423cd2

Browse files
author
王鹏
committed
feat(HARD): add _115_numDistinct
1 parent 2ab6743 commit a423cd2

File tree

1 file changed

+139
-0
lines changed

1 file changed

+139
-0
lines changed
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
package pp.arithmetic.leetcode;
2+
3+
import pp.arithmetic.Util;
4+
5+
/**
6+
* Created by wangpeng on 2019-12-13.
7+
* 115. 不同的子序列
8+
*
9+
* 给定一个字符串 S 和一个字符串 T,计算在 S 的子序列中 T 出现的个数。
10+
*
11+
* 一个字符串的一个子序列是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。(例如,"ACE" 是 "ABCDE" 的一个子序列,而 "AEC" 不是)
12+
*
13+
* 示例 1:
14+
*
15+
* 输入: S = "rabbbit", T = "rabbit"
16+
* 输出: 3
17+
* 解释:
18+
*
19+
* 如下图所示, 有 3 种可以从 S 中得到 "rabbit" 的方案。
20+
* (上箭头符号 ^ 表示选取的字母)
21+
*
22+
* rabbbit
23+
* ^^^^ ^^
24+
* rabbbit
25+
* ^^ ^^^^
26+
* rabbbit
27+
* ^^^ ^^^
28+
* 示例 2:
29+
*
30+
* 输入: S = "babgbag", T = "bag"
31+
* 输出: 5
32+
* 解释:
33+
*
34+
* 如下图所示, 有 5 种可以从 S 中得到 "bag" 的方案。
35+
* (上箭头符号 ^ 表示选取的字母)
36+
*
37+
* babgbag
38+
* ^^ ^
39+
* babgbag
40+
* ^^ ^
41+
* babgbag
42+
* ^ ^^
43+
* babgbag
44+
* ^ ^^
45+
* babgbag
46+
* ^^^
47+
*
48+
* 来源:力扣(LeetCode)
49+
* 链接:https://leetcode-cn.com/problems/distinct-subsequences
50+
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
51+
*/
52+
public class _115_numDistinct {
53+
54+
public static void main(String[] args) {
55+
_115_numDistinct numDistinct = new _115_numDistinct();
56+
System.out.println(numDistinct.numDistinct("aaa", "aa"));
57+
System.out.println(numDistinct.numDistinct("rabbbit", "rabbit"));
58+
System.out.println(numDistinct.numDistinct("babgbag", "bag"));
59+
System.out.println(numDistinct.numDistinct("adbdadeecadeadeccaeaabdabdbcdabddddabcaaadbabaaedeeddeaeebcdeabcaaaeeaeeabcddcebddebeebedaecccbdcbcedbdaeaedcdebeecdaaedaacadbdccabddaddacdddc", "bcddceeeebecbc"));
60+
Util.printDivideLine();
61+
System.out.println(numDistinct.numDistinct2("babgbag", "bag"));
62+
System.out.println(numDistinct.numDistinct2("aaa", "aa"));
63+
System.out.println(numDistinct.numDistinct2("rabbbit", "rabbit"));
64+
System.out.println(numDistinct.numDistinct2("adbdadeecadeadeccaeaabdabdbcdabddddabcaaadbabaaedeeddeaeebcdeabcaaaeeaeeabcddcebddebeebedaecccbdcbcedbdaeaedcdebeecdaaedaacadbdccabddaddacdddc", "bcddceeeebecbc"));
65+
}
66+
67+
/**
68+
* 解题思路:
69+
* 通过模拟题意中的过程,感知有点回溯的感觉:
70+
* 1、优先匹配前面的
71+
* 2、匹配上了之后,再匹配后面的
72+
* 3、直到匹配到最后一个,向后搜索匹配的,直到末尾
73+
* 4、最后一位匹配到末尾之后,倒数第二位向后搜索匹配
74+
* 5、如此循环,直至第一位也匹配到末尾结束
75+
*
76+
* 可解题,遇到复杂的提交超时:
77+
* 比如这跟case:
78+
* "adbdadeecadeadeccaeaabdabdbcdabddddabcaaadbabaaedeeddeaeebcdeabcaaaeeaeeabcddcebddebeebedaecccbdcbcedbdaeaedcdebeecdaaedaacadbdccabddaddacdddc"
79+
* "bcddceeeebecbc"
80+
* 本地跑出结果:700531452
81+
*
82+
* 优化思考:是不是可以考虑将遍历过程中的一些结果保存起来,而不是每次凑重新计算==>动态规划
83+
*
84+
* @param s
85+
* @param t
86+
* @return
87+
*/
88+
public int numDistinct(String s, String t) {
89+
if (s.length() < t.length()) return 0;
90+
int sum = 0;
91+
int ti = 0;
92+
int si = 0;
93+
while (si < s.length() && ti < t.length()) {
94+
if (s.charAt(si) == t.charAt(ti)) {
95+
if (si + 1 < s.length() && ti + 1 < t.length()) {
96+
sum += numDistinct(s.substring(si + 1), t.substring(ti + 1));
97+
} else {
98+
if (ti == t.length() - 1) {
99+
sum += 1;
100+
}
101+
}
102+
}
103+
si++;
104+
}
105+
106+
return sum;
107+
}
108+
109+
/**
110+
* 优化求解:找递进规律(s:babgbag,t:bag)
111+
* T/S "" b a b g b a g
112+
* "" 1 1 1 1 1 1 1 1
113+
* b 0 1 1 2 2 3 3 3
114+
* a 0 0 1 1 1 1 4 4
115+
* g 0 0 0 0 1 1 1 5
116+
*
117+
* dp[t.length() + 1][s.length() + 1] : dp[i][j]代表t[0-i]在s[0-j]中的出现的次数
118+
* 如果某一位t[i]==s[j],则此时的次数=dp[i-1][j-1]+dp[i][j-1]
119+
* 如果某一位t[i]!=s[j],则此时的次数=dp[i][j-1]
120+
*
121+
* @param s
122+
* @param t
123+
* @return
124+
*/
125+
public int numDistinct2(String s, String t) {
126+
int[][] dp = new int[t.length() + 1][s.length() + 1];
127+
for (int j = 0; j < s.length() + 1; j++) dp[0][j] = 1;
128+
for (int i = 1; i < t.length() + 1; i++) {
129+
for (int j = 1; j < s.length() + 1; j++) {
130+
if (t.charAt(i - 1) == s.charAt(j - 1)) {
131+
dp[i][j] = dp[i - 1][j - 1] + dp[i][j - 1];
132+
} else {
133+
dp[i][j] = dp[i][j - 1];
134+
}
135+
}
136+
}
137+
return dp[t.length()][s.length()];
138+
}
139+
}

0 commit comments

Comments
 (0)