Skip to content

Commit ad5dea2

Browse files
authored
feat: add TypeScript/Rust solutions to lc problem: No.0828 (doocs#2016)
No.0828.Count Unique Characters of All Substrings of a Given String
1 parent cc5d541 commit ad5dea2

File tree

5 files changed

+139
-11
lines changed

5 files changed

+139
-11
lines changed

solution/0800-0899/0828.Count Unique Characters of All Substrings of a Given String/README.md

+51-5
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,15 @@
5656

5757
**方法一:计算每个字符的贡献**
5858

59-
对于字符串 `s` 的每个字符 $c_i$,当它在某个子字符串中仅出现一次时,它会对这个子字符串统计唯一字符时有贡献。只需对每个字符 $c_i$,计算有多少子字符串仅包含该字符一次即可
59+
对于字符串 $s$ 的每个字符 $c_i$,当它在某个子字符串中仅出现一次时,它会对这个子字符串统计唯一字符时有贡献。
6060

61-
时间复杂度 $O(n)$,其中 $n$ 为字符串 `s` 的长度。
61+
因此,我们只需要对每个字符 $c_i$,计算有多少子字符串仅包含该字符一次即可。
62+
63+
我们用一个哈希表或者长度为 $26$ 的数组 $d$,按照下标顺序存储每个字符在 $s$ 中所有出现的位置。
64+
65+
对于每个字符 $c_i$,我们遍历 $d[c_i]$ 中的每个位置 $p$,找出左侧相邻的位置 $l$ 和右侧相邻的位置 $r$,那么从位置 $p$ 向左右两边扩散,满足要求的子字符串的数量就是 $(p - l) \times (r - p)$。我们对每个字符都进行这样的操作,累加所有字符的贡献,即可得到答案。
66+
67+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串 $s$ 的长度。
6268

6369
<!-- tabs:start -->
6470

@@ -132,22 +138,62 @@ public:
132138
### **Go**
133139
134140
```go
135-
func uniqueLetterString(s string) int {
141+
func uniqueLetterString(s string) (ans int) {
136142
d := make([][]int, 26)
137143
for i := range d {
138144
d[i] = []int{-1}
139145
}
140146
for i, c := range s {
141147
d[c-'A'] = append(d[c-'A'], i)
142148
}
143-
ans := 0
144149
for _, v := range d {
145150
v = append(v, len(s))
146151
for i := 1; i < len(v)-1; i++ {
147152
ans += (v[i] - v[i-1]) * (v[i+1] - v[i])
148153
}
149154
}
150-
return ans
155+
return
156+
}
157+
```
158+
159+
### **TypeScript**
160+
161+
```ts
162+
function uniqueLetterString(s: string): number {
163+
const d: number[][] = Array.from({ length: 26 }, () => [-1]);
164+
for (let i = 0; i < s.length; ++i) {
165+
d[s.charCodeAt(i) - 'A'.charCodeAt(0)].push(i);
166+
}
167+
let ans = 0;
168+
for (const v of d) {
169+
v.push(s.length);
170+
171+
for (let i = 1; i < v.length - 1; ++i) {
172+
ans += (v[i] - v[i - 1]) * (v[i + 1] - v[i]);
173+
}
174+
}
175+
return ans;
176+
}
177+
```
178+
179+
### **Rust**
180+
181+
```rust
182+
impl Solution {
183+
pub fn unique_letter_string(s: String) -> i32 {
184+
let mut d: Vec<Vec<i32>> = vec![vec![-1; 1]; 26];
185+
for (i, c) in s.chars().enumerate() {
186+
d[(c as usize) - ('A' as usize)].push(i as i32);
187+
}
188+
let mut ans = 0;
189+
for v in d.iter_mut() {
190+
v.push(s.len() as i32);
191+
for i in 1..v.len() - 1 {
192+
ans += (v[i] - v[i - 1]) * (v[i + 1] - v[i]);
193+
}
194+
}
195+
ans as i32
196+
}
151197
}
152198
```
153199

solution/0800-0899/0828.Count Unique Characters of All Substrings of a Given String/README_EN.md

+55-3
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,18 @@ Sum of lengths of all substring is 1 + 1 + 1 + 2 + 2 + 3 = 10
5050

5151
## Solutions
5252

53+
**Solution 1: Calculate the Contribution of Each Character**
54+
55+
For each character $c_i$ in the string $s$, when it appears only once in a substring, it contributes to the count of unique characters in that substring.
56+
57+
Therefore, we only need to calculate for each character $c_i$, how many substrings contain this character only once.
58+
59+
We use a hash table or an array $d$ of length $26$, to store the positions of each character in $s$ in order of index.
60+
61+
For each character $c_i$, we iterate through each position $p$ in $d[c_i]$, find the adjacent positions $l$ on the left and $r$ on the right, then the number of substrings that meet the requirements by expanding from position $p$ to both sides is $(p - l) \times (r - p)$. We perform this operation for each character, add up the contributions of all characters, and get the answer.
62+
63+
The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the string $s$.
64+
5365
<!-- tabs:start -->
5466

5567
### **Python3**
@@ -118,22 +130,62 @@ public:
118130
### **Go**
119131
120132
```go
121-
func uniqueLetterString(s string) int {
133+
func uniqueLetterString(s string) (ans int) {
122134
d := make([][]int, 26)
123135
for i := range d {
124136
d[i] = []int{-1}
125137
}
126138
for i, c := range s {
127139
d[c-'A'] = append(d[c-'A'], i)
128140
}
129-
ans := 0
130141
for _, v := range d {
131142
v = append(v, len(s))
132143
for i := 1; i < len(v)-1; i++ {
133144
ans += (v[i] - v[i-1]) * (v[i+1] - v[i])
134145
}
135146
}
136-
return ans
147+
return
148+
}
149+
```
150+
151+
### **TypeScript**
152+
153+
```ts
154+
function uniqueLetterString(s: string): number {
155+
const d: number[][] = Array.from({ length: 26 }, () => [-1]);
156+
for (let i = 0; i < s.length; ++i) {
157+
d[s.charCodeAt(i) - 'A'.charCodeAt(0)].push(i);
158+
}
159+
let ans = 0;
160+
for (const v of d) {
161+
v.push(s.length);
162+
163+
for (let i = 1; i < v.length - 1; ++i) {
164+
ans += (v[i] - v[i - 1]) * (v[i + 1] - v[i]);
165+
}
166+
}
167+
return ans;
168+
}
169+
```
170+
171+
### **Rust**
172+
173+
```rust
174+
impl Solution {
175+
pub fn unique_letter_string(s: String) -> i32 {
176+
let mut d: Vec<Vec<i32>> = vec![vec![-1; 1]; 26];
177+
for (i, c) in s.chars().enumerate() {
178+
d[(c as usize) - ('A' as usize)].push(i as i32);
179+
}
180+
let mut ans = 0;
181+
for v in d.iter_mut() {
182+
v.push(s.len() as i32);
183+
for i in 1..v.len() - 1 {
184+
ans += (v[i] - v[i - 1]) * (v[i + 1] - v[i]);
185+
}
186+
}
187+
ans as i32
188+
}
137189
}
138190
```
139191

Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1-
func uniqueLetterString(s string) int {
1+
func uniqueLetterString(s string) (ans int) {
22
d := make([][]int, 26)
33
for i := range d {
44
d[i] = []int{-1}
55
}
66
for i, c := range s {
77
d[c-'A'] = append(d[c-'A'], i)
88
}
9-
ans := 0
109
for _, v := range d {
1110
v = append(v, len(s))
1211
for i := 1; i < len(v)-1; i++ {
1312
ans += (v[i] - v[i-1]) * (v[i+1] - v[i])
1413
}
1514
}
16-
return ans
15+
return
1716
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
impl Solution {
2+
pub fn unique_letter_string(s: String) -> i32 {
3+
let mut d: Vec<Vec<i32>> = vec![vec![-1; 1]; 26];
4+
for (i, c) in s.chars().enumerate() {
5+
d[(c as usize) - ('A' as usize)].push(i as i32);
6+
}
7+
let mut ans = 0;
8+
for v in d.iter_mut() {
9+
v.push(s.len() as i32);
10+
for i in 1..v.len() - 1 {
11+
ans += (v[i] - v[i - 1]) * (v[i + 1] - v[i]);
12+
}
13+
}
14+
ans as i32
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
function uniqueLetterString(s: string): number {
2+
const d: number[][] = Array.from({ length: 26 }, () => [-1]);
3+
for (let i = 0; i < s.length; ++i) {
4+
d[s.charCodeAt(i) - 'A'.charCodeAt(0)].push(i);
5+
}
6+
let ans = 0;
7+
for (const v of d) {
8+
v.push(s.length);
9+
10+
for (let i = 1; i < v.length - 1; ++i) {
11+
ans += (v[i] - v[i - 1]) * (v[i + 1] - v[i]);
12+
}
13+
}
14+
return ans;
15+
}

0 commit comments

Comments
 (0)