2559. Count Vowel Strings in Ranges
2559. Count Vowel Strings in Ranges
[Problem]
Intuition
- Valid string is string with starting and ending vowel.
- Let
1
: string is valid,0
: string invalid. - For each string in
words
, we can store1
if string is valid,0
if invalid. - For example:
1 2 3
index => 0 1 2 3 4 words => ["aba","bcb","ece","aa","e"] validArr => [ 1, 0, 1, 1, 1 ]
- Now, given any query, say [2,5]. Answer to this query is the sum in
validArr
from index 2 to index 5 (both inclusive). - Hence, the problem is reduced to finding the sum of values in an array in a given range.
- Prefix Sum can help us achieve this!
- Recommended: A good reference for understanding prefix sum approach is this article by @wingkwong
Approach
- For each valid string in
words
, store1
invalidArr
at the corresponding index.1 2 3 4 5 6
// Populate validArr with 1 if the word starts and ends with a vowel, otherwise 0 for (int i = 0; i < N; i++) { if (isValid(words[i], vowels)) { // Check if the word is valid vowelArr[i] = 1; // `1` means valid, else `0` } }
- Now that we have
validArr
, we just need to find sum in the ranges given inqueries
- To do this efficiently, we use PREFIX SUM
- We calculate the prefix sum of
validArr
1
2
3
4
5
6
7
8
9
// Create a prefix sum array to easily find sum in given
int[] prefix = new int[validArr.length + 1];
prefix[0] = 0;
// Compute the prefix sum
for (int i = 0; i < validArr.length; i++) {
prefix[i + 1] = prefix[i] + validArr[i];
}
The sum for any given range
[left, right]
invalidArr
will be given byprefix[right + 1] - prefix[left]
WHY?For each query in
queries
, compute the answer and store it in anans
array. ```java int[] ans = new int[queries.length]; // Array to store answers to each query
// Process each query for (int i = 0; i < queries.length; i++) { int left = queries[i][0]; // Start of the range int right = queries[i][1]; // End of the range
1
2
// Calculate the no. of valid strings in the range using prefix sum
ans[i] = prefix[right + 1] - prefix[left]; } ```
Complexity Analysis
- Time Complexity: O(N + Q)
N
: words.lengthQ
: queries.length
- Space Complexity: O(N + Q)
- Space taken by:
vowelArr
: O(N)prefix
:O(N + 1)ans
: O(Q)
- Space taken by:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
class Solution {
public int[] vowelStrings(String[] words, int[][] queries) {
// Create a set of vowels for quick lookup
Set<Character> vowels = new HashSet<>(5);
vowels.add('a');
vowels.add('e');
vowels.add('i');
vowels.add('o');
vowels.add('u');
int N = words.length; // no. of words in the array
int[] validArr = new int[N]; // array to mark words that start and end with vowels
// populate `validArr` with 1 if the word starts and ends with a vowel, otherwise 0
for (int i = 0; i < N; i++) {
if (isValid(words[i], vowels)) { // Check if the word is valid
validArr[i] = 1; // `1` means valid, else `0`
}
}
// create a prefix sum array to easily find sum in given
int[] prefix = new int[validArr.length + 1];
// ref: [https://leetcodethehardway.com/tutorials/basic-topics/prefix-sum]
prefix[0] = 0; // Initialize the first element of prefix array
// Compute the prefix sum
for (int i = 0; i < validArr.length; i++) {
prefix[i + 1] = prefix[i] + validArr[i];
}
int[] ans = new int[queries.length]; // array to store answers to each query
// process each query
for (int i = 0; i < queries.length; i++) {
int left = queries[i][0]; // start of the range
int right = queries[i][1]; // end of the range
// calculate answer using prefix sum
ans[i] = prefix[right + 1] - prefix[left];
}
return ans;
}
// method to check if a string starts and ends with a vowel
public boolean isValid(String str, Set<Character> vowels) {
return vowels.contains(str.charAt(0)) && vowels.contains(str.charAt(str.length() - 1));
}
}
This post is licensed under CC BY 4.0 by the author.