Skip to content

Commit 2c24640

Browse files
authoredAug 2, 2023
feat: add solutions to lc problem: No.1915 (doocs#1376)
No.1915.Number of Wonderful Substrings
1 parent 3a78b47 commit 2c24640

File tree

8 files changed

+232
-173
lines changed

8 files changed

+232
-173
lines changed
 

‎solution/1900-1999/1915.Number of Wonderful Substrings/README.md

+85-57
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,19 @@
7070

7171
<!-- 这里可写通用的实现逻辑 -->
7272

73-
状态压缩 + 前缀和。
73+
**方法一:前缀异或 + 计数**
7474

75-
相似题目:[1371. 每个元音包含偶数次的最长子字符串](/solution/1300-1399/1371.Find%20the%20Longest%20Substring%20Containing%20Vowels%20in%20Even%20Counts/README.md)
75+
由于字符串中只包含 $10$ 个小写字母,因此可以用一个长度为 $10$ 的二进制数表示字符串中每个字母的奇偶性,其中第 $i$ 位为 $1$ 表示第 $i$ 个字母出现了奇数次,为 $0$ 表示第 $i$ 个字母出现了偶数次。
76+
77+
我们遍历字符串的每个字符,用一个变量 $st$ 维护当前字符串的前缀异或值,用一个数组 $cnt$ 维护每个前缀异或值出现的次数,初始时 $st = 0$, $cnt[0] = 1$。
78+
79+
对于当前遍历到的字符,我们更新其前缀异或值。如果当前的前缀异或值出现了 $cnt[st]$ 次,也就意味着有 $cnt[st]$ 个子字符串满足所有字母的出现次数均为偶数,因此我们将答案增加 $cnt[st]$。此外,对于 $0 \le i < 10$,如果当前的前缀异或值 $st$ 的第 $i$ 位为 $1$,那么我们还可以找到一个字母出现了奇数次,我们将答案增加 $cnt[st \oplus (1 << i)]$。最后,我们将 $st$ 出现的次数增加 $1$。继续遍历下一个字符,直到遍历完整个字符串。
80+
81+
时间复杂度 $O(n \times \Sigma)$,空间复杂度 $O(2^{\Sigma})$,其中 $\Sigma = 10$,而 $n$ 为字符串的长度。
82+
83+
相似题目:
84+
85+
- [1371. 每个元音包含偶数次的最长子字符串](/solution/1300-1399/1371.Find%20the%20Longest%20Substring%20Containing%20Vowels%20in%20Even%20Counts/README.md)
7686

7787
<!-- tabs:start -->
7888

@@ -83,15 +93,14 @@
8393
```python
8494
class Solution:
8595
def wonderfulSubstrings(self, word: str) -> int:
86-
counter = Counter({0: 1})
87-
state = 0
88-
ans = 0
96+
cnt = Counter({0: 1})
97+
ans = st = 0
8998
for c in word:
90-
state ^= 1 << (ord(c) - ord('a'))
91-
ans += counter[state]
99+
st ^= 1 << (ord(c) - ord("a"))
100+
ans += cnt[st]
92101
for i in range(10):
93-
ans += counter[state ^ (1 << i)]
94-
counter[state] += 1
102+
ans += cnt[st ^ (1 << i)]
103+
cnt[st] += 1
95104
return ans
96105
```
97106

@@ -102,62 +111,39 @@ class Solution:
102111
```java
103112
class Solution {
104113
public long wonderfulSubstrings(String word) {
105-
int[] counter = new int[1 << 10];
106-
counter[0] = 1;
107-
int state = 0;
114+
int[] cnt = new int[1 << 10];
115+
cnt[0] = 1;
108116
long ans = 0;
117+
int st = 0;
109118
for (char c : word.toCharArray()) {
110-
state ^= (1 << (c - 'a'));
111-
ans += counter[state];
119+
st ^= 1 << (c - 'a');
120+
ans += cnt[st];
112121
for (int i = 0; i < 10; ++i) {
113-
ans += counter[state ^ (1 << i)];
122+
ans += cnt[st ^ (1 << i)];
114123
}
115-
++counter[state];
124+
++cnt[st];
116125
}
117126
return ans;
118127
}
119128
}
120129
```
121130

122-
### **JavaScript**
123-
124-
```js
125-
/**
126-
* @param {string} word
127-
* @return {number}
128-
*/
129-
var wonderfulSubstrings = function (word) {
130-
let counter = new Array(1 << 10).fill(0);
131-
counter[0] = 1;
132-
let state = 0;
133-
let ans = 0;
134-
for (let c of word) {
135-
state ^= 1 << (c.charCodeAt(0) - 'a'.charCodeAt(0));
136-
ans += counter[state];
137-
for (let i = 0; i < 10; ++i) {
138-
ans += counter[state ^ (1 << i)];
139-
}
140-
++counter[state];
141-
}
142-
return ans;
143-
};
144-
```
145-
146131
### **C++**
147132

148133
```cpp
149134
class Solution {
150135
public:
151136
long long wonderfulSubstrings(string word) {
152-
vector<int> counter(1024);
153-
counter[0] = 1;
137+
int cnt[1024] = {1};
154138
long long ans = 0;
155-
int state = 0;
139+
int st = 0;
156140
for (char c : word) {
157-
state ^= (1 << (c - 'a'));
158-
ans += counter[state];
159-
for (int i = 0; i < 10; ++i) ans += counter[state ^ (1 << i)];
160-
++counter[state];
141+
st ^= 1 << (c - 'a');
142+
ans += cnt[st];
143+
for (int i = 0; i < 10; ++i) {
144+
ans += cnt[st ^ (1 << i)];
145+
}
146+
++cnt[st];
161147
}
162148
return ans;
163149
}
@@ -167,23 +153,65 @@ public:
167153
### **Go**
168154
169155
```go
170-
func wonderfulSubstrings(word string) int64 {
171-
counter := make([]int, 1024)
172-
counter[0] = 1
173-
state := 0
174-
var ans int64
156+
func wonderfulSubstrings(word string) (ans int64) {
157+
cnt := [1024]int{1}
158+
st := 0
175159
for _, c := range word {
176-
state ^= (1 << (c - 'a'))
177-
ans += int64(counter[state])
160+
st ^= 1 << (c - 'a')
161+
ans += int64(cnt[st])
178162
for i := 0; i < 10; i++ {
179-
ans += int64(counter[state^(1<<i)])
163+
ans += int64(cnt[st^(1<<i)])
180164
}
181-
counter[state]++
165+
cnt[st]++
182166
}
183-
return ans
167+
return
168+
}
169+
```
170+
171+
### **TypeScript**
172+
173+
```ts
174+
function wonderfulSubstrings(word: string): number {
175+
const cnt: number[] = new Array(1 << 10).fill(0);
176+
cnt[0] = 1;
177+
let ans = 0;
178+
let st = 0;
179+
for (const c of word) {
180+
st ^= 1 << (c.charCodeAt(0) - 'a'.charCodeAt(0));
181+
ans += cnt[st];
182+
for (let i = 0; i < 10; ++i) {
183+
ans += cnt[st ^ (1 << i)];
184+
}
185+
cnt[st]++;
186+
}
187+
return ans;
184188
}
185189
```
186190

191+
### **JavaScript**
192+
193+
```js
194+
/**
195+
* @param {string} word
196+
* @return {number}
197+
*/
198+
var wonderfulSubstrings = function (word) {
199+
const cnt = new Array(1024).fill(0);
200+
cnt[0] = 1;
201+
let ans = 0;
202+
let st = 0;
203+
for (const c of word) {
204+
st ^= 1 << (c.charCodeAt() - 'a'.charCodeAt());
205+
ans += cnt[st];
206+
for (let i = 0; i < 10; ++i) {
207+
ans += cnt[st ^ (1 << i)];
208+
}
209+
cnt[st]++;
210+
}
211+
return ans;
212+
};
213+
```
214+
187215
### **...**
188216

189217
```

‎solution/1900-1999/1915.Number of Wonderful Substrings/README_EN.md

+73-55
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,14 @@
7171
```python
7272
class Solution:
7373
def wonderfulSubstrings(self, word: str) -> int:
74-
counter = Counter({0: 1})
75-
state = 0
76-
ans = 0
74+
cnt = Counter({0: 1})
75+
ans = st = 0
7776
for c in word:
78-
state ^= 1 << (ord(c) - ord('a'))
79-
ans += counter[state]
77+
st ^= 1 << (ord(c) - ord("a"))
78+
ans += cnt[st]
8079
for i in range(10):
81-
ans += counter[state ^ (1 << i)]
82-
counter[state] += 1
80+
ans += cnt[st ^ (1 << i)]
81+
cnt[st] += 1
8382
return ans
8483
```
8584

@@ -88,62 +87,39 @@ class Solution:
8887
```java
8988
class Solution {
9089
public long wonderfulSubstrings(String word) {
91-
int[] counter = new int[1 << 10];
92-
counter[0] = 1;
93-
int state = 0;
90+
int[] cnt = new int[1 << 10];
91+
cnt[0] = 1;
9492
long ans = 0;
93+
int st = 0;
9594
for (char c : word.toCharArray()) {
96-
state ^= (1 << (c - 'a'));
97-
ans += counter[state];
95+
st ^= 1 << (c - 'a');
96+
ans += cnt[st];
9897
for (int i = 0; i < 10; ++i) {
99-
ans += counter[state ^ (1 << i)];
98+
ans += cnt[st ^ (1 << i)];
10099
}
101-
++counter[state];
100+
++cnt[st];
102101
}
103102
return ans;
104103
}
105104
}
106105
```
107106

108-
### **JavaScript**
109-
110-
```js
111-
/**
112-
* @param {string} word
113-
* @return {number}
114-
*/
115-
var wonderfulSubstrings = function (word) {
116-
let counter = new Array(1 << 10).fill(0);
117-
counter[0] = 1;
118-
let state = 0;
119-
let ans = 0;
120-
for (let c of word) {
121-
state ^= 1 << (c.charCodeAt(0) - 'a'.charCodeAt(0));
122-
ans += counter[state];
123-
for (let i = 0; i < 10; ++i) {
124-
ans += counter[state ^ (1 << i)];
125-
}
126-
++counter[state];
127-
}
128-
return ans;
129-
};
130-
```
131-
132107
### **C++**
133108

134109
```cpp
135110
class Solution {
136111
public:
137112
long long wonderfulSubstrings(string word) {
138-
vector<int> counter(1024);
139-
counter[0] = 1;
113+
int cnt[1024] = {1};
140114
long long ans = 0;
141-
int state = 0;
115+
int st = 0;
142116
for (char c : word) {
143-
state ^= (1 << (c - 'a'));
144-
ans += counter[state];
145-
for (int i = 0; i < 10; ++i) ans += counter[state ^ (1 << i)];
146-
++counter[state];
117+
st ^= 1 << (c - 'a');
118+
ans += cnt[st];
119+
for (int i = 0; i < 10; ++i) {
120+
ans += cnt[st ^ (1 << i)];
121+
}
122+
++cnt[st];
147123
}
148124
return ans;
149125
}
@@ -153,23 +129,65 @@ public:
153129
### **Go**
154130
155131
```go
156-
func wonderfulSubstrings(word string) int64 {
157-
counter := make([]int, 1024)
158-
counter[0] = 1
159-
state := 0
160-
var ans int64
132+
func wonderfulSubstrings(word string) (ans int64) {
133+
cnt := [1024]int{1}
134+
st := 0
161135
for _, c := range word {
162-
state ^= (1 << (c - 'a'))
163-
ans += int64(counter[state])
136+
st ^= 1 << (c - 'a')
137+
ans += int64(cnt[st])
164138
for i := 0; i < 10; i++ {
165-
ans += int64(counter[state^(1<<i)])
139+
ans += int64(cnt[st^(1<<i)])
166140
}
167-
counter[state]++
141+
cnt[st]++
168142
}
169-
return ans
143+
return
170144
}
171145
```
172146

147+
### **TypeScript**
148+
149+
```ts
150+
function wonderfulSubstrings(word: string): number {
151+
const cnt: number[] = new Array(1 << 10).fill(0);
152+
cnt[0] = 1;
153+
let ans = 0;
154+
let st = 0;
155+
for (const c of word) {
156+
st ^= 1 << (c.charCodeAt(0) - 'a'.charCodeAt(0));
157+
ans += cnt[st];
158+
for (let i = 0; i < 10; ++i) {
159+
ans += cnt[st ^ (1 << i)];
160+
}
161+
cnt[st]++;
162+
}
163+
return ans;
164+
}
165+
```
166+
167+
### **JavaScript**
168+
169+
```js
170+
/**
171+
* @param {string} word
172+
* @return {number}
173+
*/
174+
var wonderfulSubstrings = function (word) {
175+
const cnt = new Array(1024).fill(0);
176+
cnt[0] = 1;
177+
let ans = 0;
178+
let st = 0;
179+
for (const c of word) {
180+
st ^= 1 << (c.charCodeAt() - 'a'.charCodeAt());
181+
ans += cnt[st];
182+
for (let i = 0; i < 10; ++i) {
183+
ans += cnt[st ^ (1 << i)];
184+
}
185+
cnt[st]++;
186+
}
187+
return ans;
188+
};
189+
```
190+
173191
### **...**
174192

175193
```
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
class Solution {
2-
public:
3-
long long wonderfulSubstrings(string word) {
4-
vector<int> counter(1024);
5-
counter[0] = 1;
6-
long long ans = 0;
7-
int state = 0;
8-
for (char c : word) {
9-
state ^= (1 << (c - 'a'));
10-
ans += counter[state];
11-
for (int i = 0; i < 10; ++i) ans += counter[state ^ (1 << i)];
12-
++counter[state];
13-
}
14-
return ans;
15-
}
1+
class Solution {
2+
public:
3+
long long wonderfulSubstrings(string word) {
4+
int cnt[1024] = {1};
5+
long long ans = 0;
6+
int st = 0;
7+
for (char c : word) {
8+
st ^= 1 << (c - 'a');
9+
ans += cnt[st];
10+
for (int i = 0; i < 10; ++i) {
11+
ans += cnt[st ^ (1 << i)];
12+
}
13+
++cnt[st];
14+
}
15+
return ans;
16+
}
1617
};
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
1-
func wonderfulSubstrings(word string) int64 {
2-
counter := make([]int, 1024)
3-
counter[0] = 1
4-
state := 0
5-
var ans int64
1+
func wonderfulSubstrings(word string) (ans int64) {
2+
cnt := [1024]int{1}
3+
st := 0
64
for _, c := range word {
7-
state ^= (1 << (c - 'a'))
8-
ans += int64(counter[state])
5+
st ^= 1 << (c - 'a')
6+
ans += int64(cnt[st])
97
for i := 0; i < 10; i++ {
10-
ans += int64(counter[state^(1<<i)])
8+
ans += int64(cnt[st^(1<<i)])
119
}
12-
counter[state]++
10+
cnt[st]++
1311
}
14-
return ans
12+
return
1513
}
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
class Solution {
2-
public long wonderfulSubstrings(String word) {
3-
int[] counter = new int[1 << 10];
4-
counter[0] = 1;
5-
int state = 0;
6-
long ans = 0;
7-
for (char c : word.toCharArray()) {
8-
state ^= (1 << (c - 'a'));
9-
ans += counter[state];
10-
for (int i = 0; i < 10; ++i) {
11-
ans += counter[state ^ (1 << i)];
12-
}
13-
++counter[state];
14-
}
15-
return ans;
16-
}
1+
class Solution {
2+
public long wonderfulSubstrings(String word) {
3+
int[] cnt = new int[1 << 10];
4+
cnt[0] = 1;
5+
long ans = 0;
6+
int st = 0;
7+
for (char c : word.toCharArray()) {
8+
st ^= 1 << (c - 'a');
9+
ans += cnt[st];
10+
for (int i = 0; i < 10; ++i) {
11+
ans += cnt[st ^ (1 << i)];
12+
}
13+
++cnt[st];
14+
}
15+
return ans;
16+
}
1717
}

‎solution/1900-1999/1915.Number of Wonderful Substrings/Solution.js

+8-8
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@
33
* @return {number}
44
*/
55
var wonderfulSubstrings = function (word) {
6-
let counter = new Array(1 << 10).fill(0);
7-
counter[0] = 1;
8-
let state = 0;
6+
const cnt = new Array(1024).fill(0);
7+
cnt[0] = 1;
98
let ans = 0;
10-
for (let c of word) {
11-
state ^= 1 << (c.charCodeAt(0) - 'a'.charCodeAt(0));
12-
ans += counter[state];
9+
let st = 0;
10+
for (const c of word) {
11+
st ^= 1 << (c.charCodeAt() - 'a'.charCodeAt());
12+
ans += cnt[st];
1313
for (let i = 0; i < 10; ++i) {
14-
ans += counter[state ^ (1 << i)];
14+
ans += cnt[st ^ (1 << i)];
1515
}
16-
++counter[state];
16+
cnt[st]++;
1717
}
1818
return ans;
1919
};
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
class Solution:
2-
def wonderfulSubstrings(self, word: str) -> int:
3-
counter = Counter({0: 1})
4-
state = 0
5-
ans = 0
6-
for c in word:
7-
state ^= 1 << (ord(c) - ord('a'))
8-
ans += counter[state]
9-
for i in range(10):
10-
ans += counter[state ^ (1 << i)]
11-
counter[state] += 1
12-
return ans
1+
class Solution:
2+
def wonderfulSubstrings(self, word: str) -> int:
3+
cnt = Counter({0: 1})
4+
ans = st = 0
5+
for c in word:
6+
st ^= 1 << (ord(c) - ord("a"))
7+
ans += cnt[st]
8+
for i in range(10):
9+
ans += cnt[st ^ (1 << i)]
10+
cnt[st] += 1
11+
return ans
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
function wonderfulSubstrings(word: string): number {
2+
const cnt: number[] = new Array(1 << 10).fill(0);
3+
cnt[0] = 1;
4+
let ans = 0;
5+
let st = 0;
6+
for (const c of word) {
7+
st ^= 1 << (c.charCodeAt(0) - 'a'.charCodeAt(0));
8+
ans += cnt[st];
9+
for (let i = 0; i < 10; ++i) {
10+
ans += cnt[st ^ (1 << i)];
11+
}
12+
cnt[st]++;
13+
}
14+
return ans;
15+
}

0 commit comments

Comments
 (0)
Please sign in to comment.