Find Words That Can Be Formed by Characters
Easy · Arrays & Hashing · Explanation and code example
Hash Table
How it works
Since we only have lowercase letters, we can use a fixed-size array of 26 elements instead of a hash map. This is more cache-friendly and avoids hash function overhead. We decrement counts as we use characters and reset the array for each new word using a stored original copy.
Steps
- Create an array
countof size 26 and populate it with frequencies fromchars. - Store a copy of
countasorgfor resetting. - For each word:
- For each character, decrement
count[c - 'a']. - If it goes negative, the word is invalid; break early.
- If valid, add the word's length to
res. - Reset
counttoorgfor the next word.
- For each character, decrement
- Return the total length.
Complexity
- Time complexity:
O(n + (m * k)) - Space complexity:
O(1)since we have at most26different characters.
Where
nis the length ofchars,mis the number of words andkis the average length of each word.
Things to watch for
Modifying the Original Character Count Map
When checking each word, you must use a fresh copy of the character counts or reset after each word. A common mistake is decrementing the original count map without restoring it, causing subsequent words to have fewer available characters than they should.
Checking Character Presence Without Frequency
It is not enough to check if a character exists in chars; you must verify that the frequency of each character in the word does not exceed its frequency in chars. For example, "aab" cannot be formed from "ab" even though both 'a' and 'b' are present.
Python code example
from typing import List
class Solution:
def countCharacters(self, words: List[str], chars: str) -> int:
count = [0] * 26
for c in chars:
count[ord(c) - ord('a')] += 1
org = count[:]
res = 0
for w in words:
good = True
for c in w:
i = ord(c) - ord('a')
count[i] -= 1
if count[i] < 0:
good = False
break
if good:
res += len(w)
for i in range(26):
count[i] = org[i]
return res
C++ code example
class Solution {
public:
int countCharacters(vector<string>& words, string chars) {
vector<int> count(26, 0);
for (char c : chars) {
count[c - 'a']++;
}
vector<int> org = count;
int res = 0;
for (string& w : words) {
bool good = true;
for (char& c : w) {
int i = c - 'a';
count[i]--;
if (count[i] < 0) {
good = false;
break;
}
}
if (good) {
res += w.length();
}
for (int i = 0; i < 26; i++) {
count[i] = org[i];
}
}
return res;
}
};
Source and license
Adapted from NeetCode’s source · MIT license. Node types are supplied by LeetCode where needed.