Maximum Number of Words You Can Type: Set Lookup
LeetCode 1935. Maximum Number of Words You Can Type gives you a sentence and a broken keyboard. You are given a string text of words separated by single spaces, and a string brokenLetters containing the distinct letters that are broken. Return the number of words in text that can be fully typed using the working keys.
A word is "typeable" only if none of its characters appear in the broken set. Even a single broken letter disqualifies the entire word.
The approach: set-based filtering
The key insight is that checking whether a character is broken needs to be fast. If you scan the brokenLetters string for every character of every word, you end up doing unnecessary repeated work. Instead, convert brokenLetters into a set first. That gives you O(1) lookups, and the rest of the problem becomes a simple loop: split the text into words, check each word against the set, and count the ones that pass.
Whenever a problem asks you to repeatedly check membership against a fixed collection, your first move should be converting that collection into a set. This single step often drops the solution from O(n * m) to O(n + m).
The code
def can_be_typed_words(text: str, brokenLetters: str) -> int:
broken = set(brokenLetters)
count = 0
for word in text.split():
if not any(ch in broken for ch in word):
count += 1
return count
- Build a set from the
brokenLettersstring. This takes O(b) time where b is the number of broken letters. - Split the text on spaces to get the list of words.
- For each word, use
any()to check if any character is in the broken set. Theany()function short-circuits, so it stops as soon as it finds the first broken character. - If no broken character is found, increment the count.
- Return the final count.
Visual walkthrough
Let's trace through text = "hello world" and brokenLetters = "ad" to see each step of the algorithm in action.
Step 1: Build a set from brokenLetters
Convert the broken letters string into a set for constant-time membership checks.
Step 2: Check "hello" against the broken set
count = 0None of the letters in "hello" (h, e, l, l, o) appear in the broken set. This word is typeable. Increment count to 1.
Step 3: Check "world" against the broken set
count = 1"world" contains "d", which is in the broken set. This word cannot be fully typed. Count stays at 1.
Step 4: Return the count
One out of two words can be fully typed. Return 1.
The diagram shows how we first build the broken set from "ad", then check each word. "hello" passes because none of its letters (h, e, l, l, o) are in the set. "world" fails because it contains "d". The final count is 1.
Complexity analysis
| Metric | Value |
|---|---|
| Time | O(n + b) |
| Space | O(b) |
Here n is the total number of characters in text and b is the length of brokenLetters. We scan every character in the text exactly once and perform an O(1) set lookup for each. The set itself uses O(b) space, which is at most 26 since brokenLetters contains only distinct lowercase English letters.
Building blocks
This problem uses two patterns that appear across many string and array problems.
Set-based membership filtering
The core of this solution is converting a list of "bad" elements into a set, then filtering items based on whether they contain any bad element. This exact pattern shows up whenever you need to validate items against a blocklist or allowlist.
- Uncommon Words from Two Sentences - Uses a frequency map (a close cousin of the set) to filter words that appear exactly once across two sentences
- Keyboard Row - Checks whether each word can be typed using letters from a single keyboard row, using set intersection
Short-circuit scanning with any()
Instead of scanning an entire word and then deciding, any() stops the moment it finds a match. This is a small optimization, but it is a pattern worth internalizing. When you only need to know whether something exists (not how many or where), short-circuit evaluation keeps your code clean and efficient.
- Valid Anagram - Uses character frequency comparison, another form of checking "does this collection satisfy a condition?"
- Longest Common Prefix - Stops scanning as soon as a mismatch is found, the same short-circuit principle applied to prefix matching
Edge cases
All letters are broken. If every letter in the alphabet is broken, no word can be typed. The answer is 0.
No letters are broken. If brokenLetters is an empty string, every word is typeable. The answer equals the number of words in text.
Single-character words. A word like "a" is blocked if "a" is in the broken set. Make sure your solution handles single-character words the same way as longer ones.
Text with one word. When the text contains no spaces, there is exactly one word to check. The result is either 0 or 1.
From understanding to recall
This problem feels simple once you see the set-based approach, and that is exactly why it is worth drilling. Easy problems like this one teach you the micro-patterns (build a set, check membership, filter based on a condition) that become automatic building blocks in harder problems. When you encounter a medium or hard problem that requires set-based filtering as one step in a larger algorithm, you do not want to spend any time thinking about the filtering part. It should be muscle memory.
Spaced repetition helps you get there. By revisiting this problem at increasing intervals, you reinforce the pattern until it fires automatically. The goal is not to memorize the solution. The goal is to make the "convert to set, then filter" instinct so natural that you reach for it without hesitation in a timed interview setting.
Related posts
- Group Anagrams - A string problem that also uses set/hash-based character analysis
- Contains Duplicate - Another problem where a set provides instant lookup