Skip to content

feat: add TypeScript/Rust solutions to lc problem: No.0828 #2016

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,15 @@

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

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

时间复杂度 $O(n)$,其中 $n$ 为字符串 `s` 的长度。
因此,我们只需要对每个字符 $c_i$,计算有多少子字符串仅包含该字符一次即可。

我们用一个哈希表或者长度为 $26$ 的数组 $d$,按照下标顺序存储每个字符在 $s$ 中所有出现的位置。

对于每个字符 $c_i$,我们遍历 $d[c_i]$ 中的每个位置 $p$,找出左侧相邻的位置 $l$ 和右侧相邻的位置 $r$,那么从位置 $p$ 向左右两边扩散,满足要求的子字符串的数量就是 $(p - l) \times (r - p)$。我们对每个字符都进行这样的操作,累加所有字符的贡献,即可得到答案。

时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串 $s$ 的长度。

<!-- tabs:start -->

Expand Down Expand Up @@ -132,22 +138,62 @@ public:
### **Go**

```go
func uniqueLetterString(s string) int {
func uniqueLetterString(s string) (ans int) {
d := make([][]int, 26)
for i := range d {
d[i] = []int{-1}
}
for i, c := range s {
d[c-'A'] = append(d[c-'A'], i)
}
ans := 0
for _, v := range d {
v = append(v, len(s))
for i := 1; i < len(v)-1; i++ {
ans += (v[i] - v[i-1]) * (v[i+1] - v[i])
}
}
return ans
return
}
```

### **TypeScript**

```ts
function uniqueLetterString(s: string): number {
const d: number[][] = Array.from({ length: 26 }, () => [-1]);
for (let i = 0; i < s.length; ++i) {
d[s.charCodeAt(i) - 'A'.charCodeAt(0)].push(i);
}
let ans = 0;
for (const v of d) {
v.push(s.length);

for (let i = 1; i < v.length - 1; ++i) {
ans += (v[i] - v[i - 1]) * (v[i + 1] - v[i]);
}
}
return ans;
}
```

### **Rust**

```rust
impl Solution {
pub fn unique_letter_string(s: String) -> i32 {
let mut d: Vec<Vec<i32>> = vec![vec![-1; 1]; 26];
for (i, c) in s.chars().enumerate() {
d[(c as usize) - ('A' as usize)].push(i as i32);
}
let mut ans = 0;
for v in d.iter_mut() {
v.push(s.len() as i32);
for i in 1..v.len() - 1 {
ans += (v[i] - v[i - 1]) * (v[i + 1] - v[i]);
}
}
ans as i32
}
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,18 @@ Sum of lengths of all substring is 1 + 1 + 1 + 2 + 2 + 3 = 10

## Solutions

**Solution 1: Calculate the Contribution of Each Character**

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.

Therefore, we only need to calculate for each character $c_i$, how many substrings contain this character only once.

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.

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.

The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the string $s$.

<!-- tabs:start -->

### **Python3**
Expand Down Expand Up @@ -118,22 +130,62 @@ public:
### **Go**

```go
func uniqueLetterString(s string) int {
func uniqueLetterString(s string) (ans int) {
d := make([][]int, 26)
for i := range d {
d[i] = []int{-1}
}
for i, c := range s {
d[c-'A'] = append(d[c-'A'], i)
}
ans := 0
for _, v := range d {
v = append(v, len(s))
for i := 1; i < len(v)-1; i++ {
ans += (v[i] - v[i-1]) * (v[i+1] - v[i])
}
}
return ans
return
}
```

### **TypeScript**

```ts
function uniqueLetterString(s: string): number {
const d: number[][] = Array.from({ length: 26 }, () => [-1]);
for (let i = 0; i < s.length; ++i) {
d[s.charCodeAt(i) - 'A'.charCodeAt(0)].push(i);
}
let ans = 0;
for (const v of d) {
v.push(s.length);

for (let i = 1; i < v.length - 1; ++i) {
ans += (v[i] - v[i - 1]) * (v[i + 1] - v[i]);
}
}
return ans;
}
```

### **Rust**

```rust
impl Solution {
pub fn unique_letter_string(s: String) -> i32 {
let mut d: Vec<Vec<i32>> = vec![vec![-1; 1]; 26];
for (i, c) in s.chars().enumerate() {
d[(c as usize) - ('A' as usize)].push(i as i32);
}
let mut ans = 0;
for v in d.iter_mut() {
v.push(s.len() as i32);
for i in 1..v.len() - 1 {
ans += (v[i] - v[i - 1]) * (v[i + 1] - v[i]);
}
}
ans as i32
}
}
```

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
func uniqueLetterString(s string) int {
func uniqueLetterString(s string) (ans int) {
d := make([][]int, 26)
for i := range d {
d[i] = []int{-1}
}
for i, c := range s {
d[c-'A'] = append(d[c-'A'], i)
}
ans := 0
for _, v := range d {
v = append(v, len(s))
for i := 1; i < len(v)-1; i++ {
ans += (v[i] - v[i-1]) * (v[i+1] - v[i])
}
}
return ans
return
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
impl Solution {
pub fn unique_letter_string(s: String) -> i32 {
let mut d: Vec<Vec<i32>> = vec![vec![-1; 1]; 26];
for (i, c) in s.chars().enumerate() {
d[(c as usize) - ('A' as usize)].push(i as i32);
}
let mut ans = 0;
for v in d.iter_mut() {
v.push(s.len() as i32);
for i in 1..v.len() - 1 {
ans += (v[i] - v[i - 1]) * (v[i + 1] - v[i]);
}
}
ans as i32
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
function uniqueLetterString(s: string): number {
const d: number[][] = Array.from({ length: 26 }, () => [-1]);
for (let i = 0; i < s.length; ++i) {
d[s.charCodeAt(i) - 'A'.charCodeAt(0)].push(i);
}
let ans = 0;
for (const v of d) {
v.push(s.length);

for (let i = 1; i < v.length - 1; ++i) {
ans += (v[i] - v[i - 1]) * (v[i + 1] - v[i]);
}
}
return ans;
}