From 131399b415c855bc0eb6a26ed288be13773a77ce Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Sat, 9 May 2026 08:21:27 +0800 Subject: [PATCH] feat: add solutions for lc No.1915 --- .../README.md | 28 +++++++++++-- .../README_EN.md | 42 +++++++++++++++++-- .../Solution.py | 6 +-- .../Solution.rs | 17 ++++++++ 4 files changed, 83 insertions(+), 10 deletions(-) create mode 100644 solution/1900-1999/1915.Number of Wonderful Substrings/Solution.rs diff --git a/solution/1900-1999/1915.Number of Wonderful Substrings/README.md b/solution/1900-1999/1915.Number of Wonderful Substrings/README.md index 26d24e4defbdc..8f2084830986c 100644 --- a/solution/1900-1999/1915.Number of Wonderful Substrings/README.md +++ b/solution/1900-1999/1915.Number of Wonderful Substrings/README.md @@ -108,13 +108,13 @@ tags: ```python class Solution: def wonderfulSubstrings(self, word: str) -> int: - cnt = Counter({0: 1}) + cnt = defaultdict(int) + cnt[0] = 1 ans = st = 0 for c in word: st ^= 1 << (ord(c) - ord("a")) ans += cnt[st] - for i in range(10): - ans += cnt[st ^ (1 << i)] + ans += sum(cnt[st ^ (1 << i)] for i in range(10)) cnt[st] += 1 return ans ``` @@ -201,6 +201,28 @@ function wonderfulSubstrings(word: string): number { } ``` +#### Rust + +```rust +impl Solution { + pub fn wonderful_substrings(word: String) -> i64 { + let mut cnt = [0i64; 1 << 10]; + cnt[0] = 1; + let mut ans: i64 = 0; + let mut st: usize = 0; + for c in word.chars() { + st ^= 1 << (c as usize - 'a' as usize); + ans += cnt[st]; + for i in 0..10 { + ans += cnt[st ^ (1 << i)]; + } + cnt[st] += 1; + } + ans + } +} +``` + #### JavaScript ```js diff --git a/solution/1900-1999/1915.Number of Wonderful Substrings/README_EN.md b/solution/1900-1999/1915.Number of Wonderful Substrings/README_EN.md index e6048268f5cc4..465ae7d4192cb 100644 --- a/solution/1900-1999/1915.Number of Wonderful Substrings/README_EN.md +++ b/solution/1900-1999/1915.Number of Wonderful Substrings/README_EN.md @@ -119,7 +119,19 @@ tags: -### Solution 1 +### Solution 1: Prefix XOR + Counting + +Since the string contains only $10$ lowercase letters, we can use a $10$-bit integer to represent the parity of each letter count in the current prefix. The $i$-th bit is $1$ if the $i$-th letter appears an odd number of times, and $0$ if it appears an even number of times. + +We iterate through each character in the string. Use a variable $st$ to maintain the current prefix XOR state, and an array $cnt$ to record how many times each prefix state has appeared. Initially, $st = 0$ and $cnt[0] = 1$. + +For each character, update the prefix XOR state. If the current state has appeared $cnt[st]$ times, it means there are $cnt[st]$ substrings in which all letter counts are even, so we add $cnt[st]$ to the answer. In addition, for $0 \le i < 10$, toggling the $i$-th bit of $st$ (i.e., $st \oplus (1 << i)$) represents substrings where exactly one letter has an odd count, so we add $cnt[st \oplus (1 << i)]$ to the answer. Finally, increment the occurrence count of $st$ by $1$, and continue. + +The time complexity is $O(n \times \Sigma)$, and the space complexity is $O(2^{\Sigma})$, where $\Sigma = 10$ and $n$ is the length of the string. + +Similar problems: + +- [1371. 每个元音包含偶数次的最长子字符串](https://github.com/doocs/leetcode/blob/main/solution/1300-1399/1371.Find%20the%20Longest%20Substring%20Containing%20Vowels%20in%20Even%20Counts/README_EN.md) @@ -128,13 +140,13 @@ tags: ```python class Solution: def wonderfulSubstrings(self, word: str) -> int: - cnt = Counter({0: 1}) + cnt = defaultdict(int) + cnt[0] = 1 ans = st = 0 for c in word: st ^= 1 << (ord(c) - ord("a")) ans += cnt[st] - for i in range(10): - ans += cnt[st ^ (1 << i)] + ans += sum(cnt[st ^ (1 << i)] for i in range(10)) cnt[st] += 1 return ans ``` @@ -221,6 +233,28 @@ function wonderfulSubstrings(word: string): number { } ``` +#### Rust + +```rust +impl Solution { + pub fn wonderful_substrings(word: String) -> i64 { + let mut cnt = [0i64; 1 << 10]; + cnt[0] = 1; + let mut ans: i64 = 0; + let mut st: usize = 0; + for c in word.chars() { + st ^= 1 << (c as usize - 'a' as usize); + ans += cnt[st]; + for i in 0..10 { + ans += cnt[st ^ (1 << i)]; + } + cnt[st] += 1; + } + ans + } +} +``` + #### JavaScript ```js diff --git a/solution/1900-1999/1915.Number of Wonderful Substrings/Solution.py b/solution/1900-1999/1915.Number of Wonderful Substrings/Solution.py index ac616e624ec8b..46efcc9724ff5 100644 --- a/solution/1900-1999/1915.Number of Wonderful Substrings/Solution.py +++ b/solution/1900-1999/1915.Number of Wonderful Substrings/Solution.py @@ -1,11 +1,11 @@ class Solution: def wonderfulSubstrings(self, word: str) -> int: - cnt = Counter({0: 1}) + cnt = defaultdict(int) + cnt[0] = 1 ans = st = 0 for c in word: st ^= 1 << (ord(c) - ord("a")) ans += cnt[st] - for i in range(10): - ans += cnt[st ^ (1 << i)] + ans += sum(cnt[st ^ (1 << i)] for i in range(10)) cnt[st] += 1 return ans diff --git a/solution/1900-1999/1915.Number of Wonderful Substrings/Solution.rs b/solution/1900-1999/1915.Number of Wonderful Substrings/Solution.rs new file mode 100644 index 0000000000000..0b17946c25445 --- /dev/null +++ b/solution/1900-1999/1915.Number of Wonderful Substrings/Solution.rs @@ -0,0 +1,17 @@ +impl Solution { + pub fn wonderful_substrings(word: String) -> i64 { + let mut cnt = [0i64; 1 << 10]; + cnt[0] = 1; + let mut ans: i64 = 0; + let mut st: usize = 0; + for c in word.chars() { + st ^= 1 << (c as usize - 'a' as usize); + ans += cnt[st]; + for i in 0..10 { + ans += cnt[st ^ (1 << i)]; + } + cnt[st] += 1; + } + ans + } +}