diff --git a/solution/0800-0899/0828.Count Unique Characters of All Substrings of a Given String/README.md b/solution/0800-0899/0828.Count Unique Characters of All Substrings of a Given String/README.md index 1405631903d2a..b88fd847b8230 100644 --- a/solution/0800-0899/0828.Count Unique Characters of All Substrings of a Given String/README.md +++ b/solution/0800-0899/0828.Count Unique Characters of All Substrings of a Given String/README.md @@ -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$ 的长度。 @@ -132,7 +138,7 @@ 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} @@ -140,14 +146,54 @@ func uniqueLetterString(s string) int { 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![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 + } } ``` diff --git a/solution/0800-0899/0828.Count Unique Characters of All Substrings of a Given String/README_EN.md b/solution/0800-0899/0828.Count Unique Characters of All Substrings of a Given String/README_EN.md index d3c3afc8dd134..2a79ae28bf477 100644 --- a/solution/0800-0899/0828.Count Unique Characters of All Substrings of a Given String/README_EN.md +++ b/solution/0800-0899/0828.Count Unique Characters of All Substrings of a Given String/README_EN.md @@ -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$. + ### **Python3** @@ -118,7 +130,7 @@ 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} @@ -126,14 +138,54 @@ func uniqueLetterString(s string) int { 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![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 + } } ``` diff --git a/solution/0800-0899/0828.Count Unique Characters of All Substrings of a Given String/Solution.go b/solution/0800-0899/0828.Count Unique Characters of All Substrings of a Given String/Solution.go index bd3f10ae7bca7..6b279c6939c39 100644 --- a/solution/0800-0899/0828.Count Unique Characters of All Substrings of a Given String/Solution.go +++ b/solution/0800-0899/0828.Count Unique Characters of All Substrings of a Given String/Solution.go @@ -1,4 +1,4 @@ -func uniqueLetterString(s string) int { +func uniqueLetterString(s string) (ans int) { d := make([][]int, 26) for i := range d { d[i] = []int{-1} @@ -6,12 +6,11 @@ func uniqueLetterString(s string) int { 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 } \ No newline at end of file diff --git a/solution/0800-0899/0828.Count Unique Characters of All Substrings of a Given String/Solution.rs b/solution/0800-0899/0828.Count Unique Characters of All Substrings of a Given String/Solution.rs new file mode 100644 index 0000000000000..56fa5de3f820c --- /dev/null +++ b/solution/0800-0899/0828.Count Unique Characters of All Substrings of a Given String/Solution.rs @@ -0,0 +1,16 @@ +impl Solution { + pub fn unique_letter_string(s: String) -> i32 { + let mut d: Vec> = 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 + } +} diff --git a/solution/0800-0899/0828.Count Unique Characters of All Substrings of a Given String/Solution.ts b/solution/0800-0899/0828.Count Unique Characters of All Substrings of a Given String/Solution.ts new file mode 100644 index 0000000000000..120247a27e2c5 --- /dev/null +++ b/solution/0800-0899/0828.Count Unique Characters of All Substrings of a Given String/Solution.ts @@ -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; +}