Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 99b45c6

Browse files
✨feat: update 828
1 parent d4fa39a commit 99b45c6

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

‎Index/线性 DP.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
| [678. 有效的括号字符串](https://leetcode-cn.com/problems/valid-parenthesis-string/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/valid-parenthesis-string/solution/gong-shui-san-xie-yi-ti-shuang-jie-dong-801rq/) | 中等 | 🤩🤩🤩🤩🤩 |
1717
| [688. 骑士在棋盘上的概率](https://leetcode-cn.com/problems/knight-probability-in-chessboard/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/knight-probability-in-chessboard/solution/gong-shui-san-xie-jian-dan-qu-jian-dp-yu-st8l/) | 中等 | 🤩🤩🤩🤩🤩 |
1818
| [741. 摘樱桃](https://leetcode.cn/problems/cherry-pickup/) | [LeetCode 题解链接](https://leetcode.cn/problems/cherry-pickup/solution/by-ac_oier-pz7i/) | 困难 | 🤩🤩🤩🤩 |
19+
| [828. 统计子串中的唯一字符](https://leetcode.cn/problems/count-unique-characters-of-all-substrings-of-a-given-string/) | [LeetCode 题解链接](https://leetcode.cn/problems/count-unique-characters-of-all-substrings-of-a-given-string/solution/by-ac_oier-922k/) | 困难 | 🤩🤩🤩🤩 |
1920
| [978. 最长湍流子数组](https://leetcode-cn.com/problems/longest-turbulent-subarray/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/longest-turbulent-subarray/solution/xiang-jie-dong-tai-gui-hua-ru-he-cai-dp-3spgj/) | 中等 | 🤩🤩🤩🤩 |
2021
| [1137. 第 N 个泰波那契数](https://leetcode-cn.com/problems/n-th-tribonacci-number/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/n-th-tribonacci-number/solution/gong-shui-san-xie-yi-ti-si-jie-die-dai-d-m1ie/) | 简单 | 🤩🤩🤩🤩 |
2122
| [1220. 统计元音字母序列的数目](https://leetcode-cn.com/problems/count-vowels-permutation/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/count-vowels-permutation/solution/gong-shui-san-xie-yi-ti-shuang-jie-xian-n8f4o/) | 困难 | 🤩🤩🤩🤩 |

‎LeetCode/821-830/828. 统计子串中的唯一字符(困难).md‎

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
这是 LeetCode 上的 **[828. 统计子串中的唯一字符](https://leetcode.cn/problems/count-unique-characters-of-all-substrings-of-a-given-string/solution/by-ac_oier-922k/)** ,难度为 **困难**
44

5-
Tag : 「模拟」、「数学」
5+
Tag : 「模拟」、「数学」、「线性 DP」
66

77

88

@@ -110,6 +110,59 @@ function uniqueLetterString(s: string): number {
110110

111111
---
112112

113+
### 线性 DP
114+
115+
另外一个实现思路是利用「动态规划」思想。
116+
117+
定义 $f[i]$ 为考虑以 $s[i]$ 为结尾的所有子串中的唯一字符个数。
118+
119+
不失一般性考虑 $f[i]$ 该如何转移:以 $s[i]$ 为结尾的子串包括在所有以 $s[i - 1]$ 为结尾的子串结尾添加一个字符而来,以及 $s[i]$ 字符本身组成的新子串。
120+
121+
首先我们令 $f[i] = f[i - 1],ドル同时使用 $b[x]$ 记录字符 $x$ 前一次出现的下标,使用 $a[x]$ 记录字符 $x$ 在上上次出现的下标,然后假设当前处理的字符为 $c = s[i],ドル考虑 $s[i]$ 对 $f[i]$ 的影响(注意 $s[i]$ 始终为子串右端点):
122+
123+
* 在子串左端点下标范围在 $[b[c] + 1, i]$ 的子串中,$s[i]$ 必然只出现一次(满足唯一字符要求),即可增加 $i - b[c]$ 个唯一字符 $s[i]$;
124+
* 在子串左端点下标范围在 $[a[c] + 1, b[c]]$ 的子串中,原本位于 $b[c]$ 的字符在新子串中出现次数变为 2ドル$ 次(不再满足唯一字符要求),即需减少 $b[c] - a[c]$ 个唯一字符 $s[i]$。
125+
126+
综上,我们有状态转移方程:$f[i] = f[i - 1] + (i - b[s[i]]) - (b[s[i]] - a[s[i]])$
127+
128+
实现上,由于 $f[i]$ 只依赖于 $f[i - 1],ドル因此我们真的无须创建动规数组,而只需要使用单个变量 `cur` 来记录当前处理到的 $f[i]$ 即可,累积所有的 $f[i]$ 即是答案。
129+
130+
Java 代码:
131+
```Java
132+
class Solution {
133+
public int uniqueLetterString(String s) {
134+
int n = s.length(), ans = 0, cur = 0;
135+
int[] a = new int[26], b = new int[26];
136+
Arrays.fill(a, -1); Arrays.fill(b, -1);
137+
for (int i = 0; i < n; i++) {
138+
int u = s.charAt(i) - 'A';
139+
cur += i - b[u] - (b[u] - a[u]);
140+
ans += cur;
141+
a[u] = b[u]; b[u] = i;
142+
}
143+
return ans;
144+
}
145+
}
146+
```
147+
TypeScript 代码:
148+
```TypeScript
149+
function uniqueLetterString(s: string): number {
150+
let n = s.length, ans = 0, cur = 0
151+
const a = new Array<number>(26).fill(-1), b = new Array<number>(26).fill(-1)
152+
for (let i = 0; i < n; i++) {
153+
const u = s.charCodeAt(i) - 65
154+
cur += i - b[u] - (b[u] - a[u])
155+
ans += cur
156+
a[u] = b[u]; b[u] = i
157+
}
158+
return ans
159+
};
160+
```
161+
* 时间复杂度:$O(n)$
162+
* 空间复杂度:$O(C),ドル其中 $C = 26$ 为字符集大小
163+
164+
---
165+
113166
### 最后
114167

115168
这是我们「刷穿 LeetCode」系列文章的第 `No.828` 篇,系列开始于 2021年01月01日,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /