puzzle
string, a word
is valid if both the following conditions are satisfied:
word
contains the first letter of puzzle
.word
, that letter is in puzzle
.
"abcdefg"
, then valid words are "faced"
, "cabbage"
, and "baggage"
, while"beefed"
(does not include 'a'
) and "based"
(includes 's'
which is not in the puzzle).answer
, where answer[i]
is the number of words in the given word list words
that is valid with respect to the puzzle puzzles[i]
.
Example 1:
Input: words = ["aaaa","asas","able","ability","actt","actor","access"], puzzles = ["aboveyz","abrodyz","abslute","absoryz","actresz","gaswxyz"] Output: [1,1,3,2,4,0] Explanation: 1 valid word for "aboveyz" : "aaaa" 1 valid word for "abrodyz" : "aaaa" 3 valid words for "abslute" : "aaaa", "asas", "able" 2 valid words for "absoryz" : "aaaa", "asas" 4 valid words for "actresz" : "aaaa", "asas", "actt", "access" There are no valid words for "gaswxyz" cause none of the words in the list contains letter 'g'.
Example 2:
Input: words = ["apple","pleas","please"], puzzles = ["aelwxyz","aelpxyz","aelpsxy","saelpxy","xaelpsy"] Output: [0,1,3,2,0]
Constraints:
1 <= words.length <= 105
4 <= words[i].length <= 50
1 <= puzzles.length <= 104
puzzles[i].length == 7
words[i]
and puzzles[i]
consist of lowercase English letters.puzzles[i]
does not contain repeated characters.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
For each puzzle, we check every word in the word list to see if it's a valid word for that puzzle. We do this by examining each word against the rules of a given puzzle.
Here's how the algorithm would work step-by-step:
def number_of_valid_words(words, puzzles):
result = []
for puzzle in puzzles:
valid_word_count = 0
# Iterate through each word to check against current puzzle.
for word in words:
first_letter_of_puzzle = puzzle[0]
# Optimization: Word must contain first letter of puzzle.
if first_letter_of_puzzle in word:
is_valid = True
# Ensure all letters in the word are present in puzzle.
for letter in word:
if letter not in puzzle:
is_valid = False
break
if is_valid:
valid_word_count += 1
result.append(valid_word_count)
return result
The key idea is to represent each word and puzzle as a set of letters. Then, for each puzzle, we efficiently check which words are valid by ensuring the word's letters are a subset of the puzzle's letters and that the word contains the puzzle's first letter.
Here's how the algorithm would work step-by-step:
def find_num_valid_words(words, puzzles):
puzzle_results = []
for puzzle in puzzles:
puzzle_mask = 0
for char in puzzle:
puzzle_mask |= (1 << (ord(char) - ord('a')))
first_letter_mask = (1 << (ord(puzzle[0]) - ord('a')))
valid_word_count = 0
for word in words:
word_mask = 0
for char in word:
word_mask |= (1 << (ord(char) - ord('a')))
# Check if word is subset of puzzle and contains first letter
if (word_mask & puzzle_mask) == word_mask:
# Verifies the word contains the puzzle's first letter
if (word_mask & first_letter_mask) != 0:
valid_word_count += 1
puzzle_results.append(valid_word_count)
# Returns the count of valid words for each puzzle
return puzzle_results
Case | How to Handle |
---|---|
Null or empty words array | Return a list of zeros with the same length as puzzles array. |
Null or empty puzzles array | Return an empty list since no puzzles to process exist. |
Empty string in words array | Treat empty string as no matching letters so it never contributes to a count. |
Empty string in puzzles array | No word will ever be valid for the empty puzzle so the count is zero. |
Words or puzzles with very long strings (close to maximum string length) | Ensure the bitmask approach used to represent the letters in words and puzzles handles potentially long string inputs without memory issues. |
All words contain only the first letter of a given puzzle. | The solution must correctly count all such words as valid for that puzzle if all other letters in the word are in the puzzle. |
Words or puzzles contain duplicate letters. | The set or bitmask representation will naturally handle duplicate letters without error. |
Maximum number of words and puzzles are provided to test for performance bottlenecks. | Evaluate the time complexity, ensuring bit manipulation is efficient and the solution scales linearly or better with the number of words and puzzles. |