Skip to content

Commit 4dd5850

Browse files
committed
feat: leetcode 940
1 parent 9fa35bf commit 4dd5850

File tree

8 files changed

+116
-1
lines changed

8 files changed

+116
-1
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<p align="center">
44
<!-- TOPICS COUNT START -->
5-
<img src="https://img.shields.io/badge/-进度:519-green" alt="进度:519">
5+
<img src="https://img.shields.io/badge/-进度:520-green" alt="进度:520">
66
<!-- TOPICS COUNT END -->
77
<a href="./assets/docs/TOPICS.md"><img src="https://img.shields.io/badge/-题库目录-blue" alt="题库目录"></a>
88
<a href="./assets/docs/CATEGORIES.md"><img src="https://img.shields.io/badge/-题库分类-red" alt="题库分类"></a>

assets/data/categories.json

+6
Original file line numberDiff line numberDiff line change
@@ -1639,6 +1639,12 @@
16391639
"path": "./problemset/flip-string-to-monotone-increasing/README.md",
16401640
"difficulty": "中等"
16411641
},
1642+
{
1643+
"id": "940",
1644+
"title": "不同的子序列 II",
1645+
"path": "./problemset/distinct-subsequences-2/README.md",
1646+
"difficulty": "困难"
1647+
},
16421648
{
16431649
"id": "1800",
16441650
"title": "最大升序子数组和",

assets/data/topics.json

+10
Original file line numberDiff line numberDiff line change
@@ -4149,6 +4149,16 @@
41494149
"url": "https://leetcode-cn.com/problems/reorder-data-in-log-files/",
41504150
"path": "./problemset/reorder-data-in-log-files/README.md"
41514151
},
4152+
{
4153+
"id": "940",
4154+
"title": {
4155+
"cn": "不同的子序列 II",
4156+
"en": "distinct-subsequences-2"
4157+
},
4158+
"difficulty": "困难",
4159+
"url": "https://leetcode.cn/problems/distinct-subsequences-ii/",
4160+
"path": "./problemset/distinct-subsequences-2/README.md"
4161+
},
41524162
{
41534163
"id": "942",
41544164
"title": {

assets/docs/CATEGORIES.md

+1
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@
306306
| 871. [最低加油次数](../../problemset/minimum-number-of-refueling-stops/README.md) | 困难 |
307307
| 873. [最长的斐波那契子序列的长度](../../problemset/length-of-longest-fibonacci-subsequence/README.md) | 中等 |
308308
| 926. [将字符串翻转到单调递增](../../problemset/flip-string-to-monotone-increasing/README.md) | 中等 |
309+
| 940. [不同的子序列 II](../../problemset/distinct-subsequences-2/README.md) | 困难 |
309310
| 1800. [最大升序子数组和](../../problemset/maximum-ascending-subarray-sum/README.md) | 简单 |
310311
| 1994. [好子集的数目](../../problemset/the-number-of-good-subsets/README.md) | 困难 |
311312
| 2100. [适合打劫银行的日子](../../problemset/find-good-days-to-rob-the-bank/README.md) | 中等 |

assets/docs/TOPICS.md

+2
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,8 @@
830830

831831
[937. 重新排列日志文件](../../problemset/reorder-data-in-log-files/README.md)
832832

833+
[940. 不同的子序列 II](../../problemset/distinct-subsequences-2/README.md)
834+
833835
[942. 增减字符串匹配](../../problemset/di-string-match/README.md)
834836

835837
[944. 删列造序](../../problemset/delete-columns-to-make-sorted/README.md)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# 不同的子序列 II
2+
3+
> 难度:困难
4+
>
5+
> https://leetcode.cn/problems/distinct-subsequences-ii/
6+
7+
## 题目
8+
9+
给定一个字符串 `s`,计算 `s`**不同非空子序列** 的个数。因为结果可能很大,所以返回答案需要对 `10^9 + 7` 取余 。
10+
11+
字符串的 **子序列** 是经由原字符串删除一些(也可能不删除)字符但不改变剩余字符相对位置的一个新字符串。
12+
13+
- 例如,`"ace"``"abcde"` 的一个子序列,但 `"aec"` 不是。
14+
 
15+
### 示例
16+
17+
#### 示例 1:
18+
19+
```
20+
输入:s = "abc"
21+
输出:7
22+
解释:7 个不同的子序列分别是 "a", "b", "c", "ab", "ac", "bc", 以及 "abc"。
23+
```
24+
25+
#### 示例 2:
26+
27+
```
28+
输入:s = "aba"
29+
输出:6
30+
解释:6 个不同的子序列分别是 "a", "b", "ab", "ba", "aa" 以及 "aba"。
31+
```
32+
33+
#### 示例 3:
34+
35+
```
36+
输入:s = "aaa"
37+
输出:3
38+
解释:3 个不同的子序列分别是 "a", "aa" 以及 "aaa"。
39+
```
40+
41+
## 解题
42+
43+
```ts
44+
/**
45+
* 动态规划
46+
* @desc 时间复杂度 O(N+|Σ|) 空间复杂度 O(|Σ|)
47+
* @param s
48+
* @returns
49+
*/
50+
export function distinctSubseqII(s: string): number {
51+
const MOD = 1000000007
52+
const g = new Array(26).fill(0)
53+
const n = s.length; let total = 0
54+
for (let i = 0; i < n; ++i) {
55+
const oi = s[i].charCodeAt(0) - 'a'.charCodeAt(0)
56+
const prev = g[oi]
57+
g[oi] = (total + 1) % MOD
58+
total = ((total + g[oi] - prev) % MOD + MOD) % MOD
59+
}
60+
return total
61+
}
62+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { describe, expect, it } from 'vitest'
2+
import { distinctSubseqII } from '.'
3+
4+
describe('不同的子序列 II', () => {
5+
testCase(distinctSubseqII)
6+
})
7+
8+
function testCase(fn: typeof distinctSubseqII) {
9+
it.each([
10+
['abc', 7],
11+
['aba', 6],
12+
['aaa', 3],
13+
])('示例%#', (s, expected) => {
14+
expect(fn(s)).toBe(expected)
15+
})
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/**
2+
* 动态规划
3+
* @desc 时间复杂度 O(N+|Σ|) 空间复杂度 O(|Σ|)
4+
* @param s
5+
* @returns
6+
*/
7+
export function distinctSubseqII(s: string): number {
8+
const MOD = 1000000007
9+
const g = new Array(26).fill(0)
10+
const n = s.length; let total = 0
11+
for (let i = 0; i < n; ++i) {
12+
const oi = s[i].charCodeAt(0) - 'a'.charCodeAt(0)
13+
const prev = g[oi]
14+
g[oi] = (total + 1) % MOD
15+
total = ((total + g[oi] - prev) % MOD + MOD) % MOD
16+
}
17+
return total
18+
}

0 commit comments

Comments
 (0)