916. Word Subsets
916. Word Subsets
[Problem]
Intuition
The question is pretty straightforward, it asks us to verify which words in array
words1
are universal or not.Lets call the arrays
words1
->A
andwords2
->B
- Now observe this example:
1 2
A = ["aabc", "ef", "xaaaabcd", "abccdefaa"]; B = ["aaac", "aab", "ccbd"];
What characters do we need in any string in
A
to be universal?- Let us observe the frequencies of all characters in strings in
B
1 2 3 4 5 6 7 8 9 10 11 12 13
aaac => {a: 3, c: 1} aab => {a: 2, b: 1} ccbd => {c: 2, b: 1, d:1} For any string to be universal, it has to have 3 `a` => max frequency of `a` among all strings in `B` 2 `c` => max frequency of `c` among all strings in `B` 1 `b` => max frequency of `b` among all strings in `B` 1 `d` => max frequency of `d` among all strings in `B` ---------------------------------------------- Observe that strings in `A` that follow this requirement are: "xaaaabcd" and "abccdefaa" Hence, these two are universal strings!
Hence we need to update the maximum frequencies of characters among all strings in
B
- Now, we check if the required number of each character is present in any string in
A
. If so, it is considered universal.
Approach
For each word in
words2
, calculate max frequency of each character among all strings.1 2 3 4 5 6 7 8 9 10 11 12 13 14
// Array to store the maximum frequency of each character across all strings in `words2` int[] maxFreq = new int[26]; // calculate maxFreq of each character across all strings in `words2` for (String word : words2) { int[] currentWordFreq = new int[26]; for (char ch : word.toCharArray()) { currentWordFreq[ch - 'a']++; // Update maxFreq for each character maxFreq[ch - 'a'] = Math.max(maxFreq[ch - 'a'], currentWordFreq[ch - 'a']); } }
Now traverse through each word in
words1
, make its character frequency array, and check if the string is universal1 2 3 4 5 6 7 8 9 10 11 12
for (String word : words1) { // frequency array for the current word in words1 int[] wordFreq = new int[26]; for (char ch : word.toCharArray()) { wordFreq[ch - 'a']++; } // check if the word is universal if (isUniversal(wordFreq, maxFreq)) { universalWords.add(word); } }
isUniversal
method: When themaxFreq[i] > wordFreq[i]
, means there are NOT enough no. of current character in this word to become universal.1 2 3 4 5 6 7 8 9 10 11
// method to check if a word is universal private boolean isUniversal(int[] wordFreq, int[] maxFreq) { // verify if `wordFreq` satisfies the `maxFreq` for all characters for (int i = 0; i < 26; i++) { // `maxFreq[i]` is minimum frequency we need for `wordFreq[i]` if (maxFreq[i] > wordFreq[i]) { return false; } } return true; }
Complexity Analysis
- Time Complexity: O(N + M)
N
: Total characters across all strings inwords1
M
: Total characters across all strings inwords2
- Space Complexity: O(n + m)
n
: words1.lengthm
: words2.length
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 List<String> wordSubsets(String[] words1, String[] words2) {
// Array to store the maximum frequency of each character across all strings in `words2`
int[] maxFreq = new int[26];
// calculate maxFreq of each character across all strings in `words2`
for (String word : words2) {
int[] currentWordFreq = new int[26];
for (char ch : word.toCharArray()) {
currentWordFreq[ch - 'a']++;
// update maxFreq for each character
maxFreq[ch - 'a'] = Math.max(maxFreq[ch - 'a'], currentWordFreq[ch - 'a']);
}
}
// storing universal strings
List<String> universalWords = new ArrayList<>();
for (String word : words1) {
// frequency array for the current word in words1
int[] wordFreq = new int[26];
for (char ch : word.toCharArray()) {
wordFreq[ch - 'a']++;
}
// check if the word is universal
if (isUniversal(wordFreq, maxFreq)) {
universalWords.add(word);
}
}
return universalWords;
}
// method to check if a word is universal
private boolean isUniversal(int[] wordFreq, int[] maxFreq) {
// verify if `wordFreq` satisfies the `maxFreq` for all characters
for (int i = 0; i < 26; i++) {
// `maxFreq[i]` is minimum frequency we need for `wordFreq[i]`
if (maxFreq[i] > wordFreq[i]) {
return false;
}
}
return true;
}
}
This post is licensed under CC BY 4.0 by the author.