54
54
55
55
** 方法一:预处理 + 二分查找**
56
56
57
- 预处理出所有以元音开头和结尾的字符串的下标,然后对于每个查询,统计在预处理数组中的下标范围内的字符串的数目 。
57
+ 我们可以预处理出所有以元音开头和结尾的字符串的下标,按顺序记录在数组 $nums$ 中 。
58
58
59
- 时间复杂度 $O(n + m \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 和 $m$ 分别为 ` words ` 和 ` queries ` 的长度。
59
+ 接下来,我们遍历每个查询 $(l, r)$,通过二分查找在 $nums$ 中找到第一个大于等于 $l$ 的下标 $i$,以及第一个大于 $r$ 的下标 $j$,那么当前查询的答案就是 $j - i$。
60
+
61
+ 时间复杂度 $O(n + m \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 和 $m$ 分别是数组 $words$ 和 $queries$ 的长度。
62
+
63
+ ** 方法二:前缀和**
64
+
65
+ 我们可以创建一个长度为 $n+1$ 的前缀和数组 $s$,其中 $s[ i] $ 表示数组 $words$ 的前 $i$ 个字符串中以元音开头和结尾的字符串的数目。初始时 $s[ 0] = 0$。
66
+
67
+ 接下来,我们遍历数组 $words$,如果当前字符串以元音开头和结尾,那么 $s[ i+1] = s[ i] + 1$,否则 $s[ i+1] = s[ i] $。
68
+
69
+ 最后,我们遍历每个查询 $(l, r)$,那么当前查询的答案就是 $s[ r+1] - s[ l] $。
70
+
71
+ 时间复杂度 $O(n + m)$,空间复杂度 $O(n)$。其中 $n$ 和 $m$ 分别是数组 $words$ 和 $queries$ 的长度。
60
72
61
73
<!-- tabs:start -->
62
74
67
79
``` python
68
80
class Solution :
69
81
def vowelStrings (self , words : List[str ], queries : List[List[int ]]) -> List[int ]:
70
- t = [i for i, w in enumerate (words) if w[0 ] in " aeiou" and w[- 1 ] in " aeiou" ]
71
- return [bisect_left(t, r + 1 ) - bisect_left(t, l) for l, r in queries]
82
+ vowels = set (" aeiou" )
83
+ nums = [i for i, w in enumerate (words) if w[0 ] in vowels and w[- 1 ] in vowels]
84
+ return [bisect_right(nums, r) - bisect_left(nums, l) for l, r in queries]
85
+ ```
86
+
87
+ ``` python
88
+ class Solution :
89
+ def vowelStrings (self , words : List[str ], queries : List[List[int ]]) -> List[int ]:
90
+ vowels = set (" aeiou" )
91
+ s = list (accumulate((int (w[0 ] in vowels and w[- 1 ] in vowels) for w in words), initial = 0 ))
92
+ return [s[r + 1 ] - s[l] for l, r in queries]
72
93
```
73
94
74
95
### ** Java**
@@ -77,33 +98,57 @@ class Solution:
77
98
78
99
``` java
79
100
class Solution {
101
+ private List<Integer > nums = new ArrayList<> ();
102
+
80
103
public int [] vowelStrings (String [] words , int [][] queries ) {
81
- List<Integer > t = new ArrayList<> ();
82
104
Set<Character > vowels = Set . of(' a' , ' e' , ' i' , ' o' , ' u' );
83
105
for (int i = 0 ; i < words. length; ++ i) {
84
106
char a = words[i]. charAt(0 ), b = words[i]. charAt(words[i]. length() - 1 );
85
107
if (vowels. contains(a) && vowels. contains(b)) {
86
- t . add(i);
108
+ nums . add(i);
87
109
}
88
110
}
89
- int [] ans = new int [queries. length];
90
- for (int i = 0 ; i < ans. length; ++ i) {
91
- ans[i] = search(t, queries[i][1 ] + 1 ) - search(t, queries[i][0 ]);
111
+ int m = queries. length;
112
+ int [] ans = new int [m];
113
+ for (int i = 0 ; i < m; ++ i) {
114
+ int l = queries[i][0 ], r = queries[i][1 ];
115
+ ans[i] = search(r + 1 ) - search(l);
92
116
}
93
117
return ans;
94
118
}
95
119
96
- private int search (List< Integer > nums , int x ) {
97
- int left = 0 , right = nums. size();
98
- while (left < right ) {
99
- int mid = (left + right ) >> 1 ;
120
+ private int search (int x ) {
121
+ int l = 0 , r = nums. size();
122
+ while (l < r ) {
123
+ int mid = (l + r ) >> 1 ;
100
124
if (nums. get(mid) >= x) {
101
- right = mid;
125
+ r = mid;
102
126
} else {
103
- left = mid + 1 ;
127
+ l = mid + 1 ;
104
128
}
105
129
}
106
- return left;
130
+ return l;
131
+ }
132
+ }
133
+ ```
134
+
135
+ ``` java
136
+ class Solution {
137
+ public int [] vowelStrings (String [] words , int [][] queries ) {
138
+ Set<Character > vowels = Set . of(' a' , ' e' , ' i' , ' o' , ' u' );
139
+ int n = words. length;
140
+ int [] s = new int [n + 1 ];
141
+ for (int i = 0 ; i < n; ++ i) {
142
+ char a = words[i]. charAt(0 ), b = words[i]. charAt(words[i]. length() - 1 );
143
+ s[i + 1 ] = s[i] + (vowels. contains(a) && vowels. contains(b) ? 1 : 0 );
144
+ }
145
+ int m = queries. length;
146
+ int [] ans = new int [m];
147
+ for (int i = 0 ; i < m; ++ i) {
148
+ int l = queries[i][0 ], r = queries[i][1 ];
149
+ ans[i] = s[r + 1 ] - s[l];
150
+ }
151
+ return ans;
107
152
}
108
153
}
109
154
```
@@ -114,17 +159,41 @@ class Solution {
114
159
class Solution {
115
160
public:
116
161
vector<int > vowelStrings(vector<string >& words, vector<vector<int >>& queries) {
117
- vector<int > t;
118
162
unordered_set<char > vowels = {'a', 'e', 'i', 'o', 'u'};
163
+ vector<int > nums;
119
164
for (int i = 0; i < words.size(); ++i) {
120
- if (vowels.count(words[ i] [ 0 ] ) && vowels.count(words[ i] .back())) {
121
- t.push_back(i);
165
+ char a = words[ i] [ 0 ] , b = words[ i] .back();
166
+ if (vowels.count(a) && vowels.count(b)) {
167
+ nums.push_back(i);
122
168
}
123
169
}
124
170
vector<int > ans;
125
171
for (auto& q : queries) {
126
- int x = lower_bound(t.begin(), t.end(), q[ 1] + 1) - lower_bound(t.begin(), t.end(), q[ 0] );
127
- ans.push_back(x);
172
+ int l = q[ 0] , r = q[ 1] ;
173
+ int cnt = upper_bound(nums.begin(), nums.end(), r) - lower_bound(nums.begin(), nums.end(), l);
174
+ ans.push_back(cnt);
175
+ }
176
+ return ans;
177
+ }
178
+ };
179
+ ```
180
+
181
+ ```cpp
182
+ class Solution {
183
+ public:
184
+ vector<int> vowelStrings(vector<string>& words, vector<vector<int>>& queries) {
185
+ unordered_set<char> vowels = {'a', 'e', 'i', 'o', 'u'};
186
+ int n = words.size();
187
+ int s[n + 1];
188
+ s[0] = 0;
189
+ for (int i = 0; i < n; ++i) {
190
+ char a = words[i][0], b = words[i].back();
191
+ s[i + 1] = s[i] + (vowels.count(a) && vowels.count(b));
192
+ }
193
+ vector<int> ans;
194
+ for (auto& q : queries) {
195
+ int l = q[0], r = q[1];
196
+ ans.push_back(s[r + 1] - s[l]);
128
197
}
129
198
return ans;
130
199
}
@@ -134,20 +203,89 @@ public:
134
203
### ** Go**
135
204
136
205
``` go
137
- func vowelStrings(words []string, queries [][]int) (ans []int) {
138
- vowels := "aeiou"
139
- t := []int{}
206
+ func vowelStrings (words []string , queries [][]int ) []int {
207
+ vowels := map [ byte ] bool { ' a ' : true , ' e ' : true , ' i ' : true , ' o ' : true , ' u ' : true }
208
+ nums := []int {}
140
209
for i , w := range words {
141
- if strings.Contains( vowels, w[:1]) && strings.Contains( vowels, w[len(w)-1:]) {
142
- t = append(t , i)
210
+ if vowels[w[ 0 ]] && vowels[ w[len (w)-1 ]] {
211
+ nums = append (nums , i)
143
212
}
144
213
}
145
- for _, q := range queries {
146
- i := sort.Search(len(t), func(i int) bool { return t[i] >= q[0] })
147
- j := sort.Search(len(t), func(i int) bool { return t[i] >= q[1]+1 })
148
- ans = append(ans, j-i )
214
+ ans := make ([] int , len ( queries))
215
+ for i , q := range queries {
216
+ l , r := q[ 0 ], q[1 ]
217
+ ans[i] = sort. SearchInts (nums, r+ 1 ) - sort. SearchInts (nums, l )
149
218
}
150
- return
219
+ return ans
220
+ }
221
+ ```
222
+
223
+ ``` go
224
+ func vowelStrings (words []string , queries [][]int ) []int {
225
+ vowels := map [byte ]bool {' a' : true , ' e' : true , ' i' : true , ' o' : true , ' u' : true }
226
+ n := len (words)
227
+ s := make ([]int , n+1 )
228
+ for i , w := range words {
229
+ x := 0
230
+ if vowels[w[0 ]] && vowels[w[len (w)-1 ]] {
231
+ x = 1
232
+ }
233
+ s[i+1 ] = s[i] + x
234
+ }
235
+ ans := make ([]int , len (queries))
236
+ for i , q := range queries {
237
+ l , r := q[0 ], q[1 ]
238
+ ans[i] = s[r+1 ] - s[l]
239
+ }
240
+ return ans
241
+ }
242
+ ```
243
+
244
+ ### ** TypeScript**
245
+
246
+ ``` ts
247
+ function vowelStrings(words : string [], queries : number [][]): number [] {
248
+ const vowels = new Set ([' a' , ' e' , ' i' , ' o' , ' u' ]);
249
+ const nums: number [] = [];
250
+ for (let i = 0 ; i < words .length ; ++ i ) {
251
+ if (
252
+ vowels .has (words [i ][0 ]) &&
253
+ vowels .has (words [i ][words [i ].length - 1 ])
254
+ ) {
255
+ nums .push (i );
256
+ }
257
+ }
258
+ const search = (x : number ): number => {
259
+ let l = 0 ,
260
+ r = nums .length ;
261
+ while (l < r ) {
262
+ const mid = (l + r ) >> 1 ;
263
+ if (nums [mid ] >= x ) {
264
+ r = mid ;
265
+ } else {
266
+ l = mid + 1 ;
267
+ }
268
+ }
269
+ return l ;
270
+ };
271
+ return queries .map (([l , r ]) => search (r + 1 ) - search (l ));
272
+ }
273
+ ```
274
+
275
+ ``` ts
276
+ function vowelStrings(words : string [], queries : number [][]): number [] {
277
+ const vowels = new Set ([' a' , ' e' , ' i' , ' o' , ' u' ]);
278
+ const n = words .length ;
279
+ const s: number [] = new Array (n + 1 ).fill (0 );
280
+ for (let i = 0 ; i < n ; ++ i ) {
281
+ s [i + 1 ] =
282
+ s [i ] +
283
+ (vowels .has (words [i ][0 ]) &&
284
+ vowels .has (words [i ][words [i ].length - 1 ])
285
+ ? 1
286
+ : 0 );
287
+ }
288
+ return queries .map (([l , r ]) => s [r + 1 ] - s [l ]);
151
289
}
152
290
```
153
291
0 commit comments