A clear explanation of finding characters that appear in all words using minimum frequency counts.
Problem Restatement
We are given an array of strings words.
We need to return a list of all characters that appear in every string in words, including duplicates.
If a character appears k times in every string, we include it k times in the answer.
The answer can be returned in any order.
The official constraints state that 1 <= words.length <= 100, 1 <= words[i].length <= 100, and each words[i] contains only lowercase English letters.
Input and Output
| Item | Meaning |
|---|---|
| Input | Array of strings words |
| Output | List of characters common to all words |
| Duplicates | Include as many copies as appear in every word |
Function shape:
def commonChars(words: list[str]) -> list[str]:
...Examples
Example 1:
words = ["bella", "label", "roller"]Character frequencies:
| Char | “bella” | “label” | “roller” | Min |
|---|---|---|---|---|
| b | 1 | 1 | 0 | 0 |
| e | 1 | 1 | 1 | 1 |
| l | 2 | 2 | 2 | 2 |
| r | 0 | 0 | 2 | 0 |
Common characters:
["e", "l", "l"]Example 2:
words = ["cool", "lock", "cook"]Character frequencies:
| Char | “cool” | “lock” | “cook” | Min |
|---|---|---|---|---|
| c | 1 | 1 | 2 | 1 |
| o | 2 | 1 | 2 | 1 |
| l | 1 | 1 | 0 | 0 |
| k | 0 | 1 | 1 | 0 |
Common characters:
["c", "o"]Key Insight
A character is common to all words if and only if its minimum frequency across all words is at least 1.
The number of times we include a character is its minimum frequency across all words.
So we compute the element-wise minimum of the frequency arrays for all words.
Algorithm
- Start with the frequency array of the first word.
- For each subsequent word, take the element-wise minimum with the current minimum array.
- Expand the final minimum array into a character list.
Correctness
A character c appears at least min_freq[c] times in every word because min_freq[c] is the minimum frequency of c across all words.
We include c exactly min_freq[c] times. This is the maximum number of copies of c we can include while guaranteeing each copy appears in every word.
Edge Cases
- Duplicates usually matter; store counts when a set would lose necessary multiplicity.
- Update the frequency structure in the same order the invariant assumes.
- Check empty or one-element inputs if the problem allows them.
Complexity
Let n = len(words) and m be the average word length.
| Metric | Value | Why |
|---|---|---|
| Time | O(n * m) | Process every character in every word |
| Space | O(1) | Frequency arrays are always size 26 |
Common Pitfalls
- Do not optimize away the invariant; the code should still make it clear what condition is being maintained.
- Prefer problem-specific names over one-letter variables once the logic becomes stateful.
Implementation
from collections import Counter
class Solution:
def commonChars(self, words: list[str]) -> list[str]:
min_freq = Counter(words[0])
for word in words[1:]:
word_freq = Counter(word)
for ch in min_freq:
min_freq[ch] = min(min_freq[ch], word_freq.get(ch, 0))
result = []
for ch, count in min_freq.items():
result.extend([ch] * count)
return resultCode Explanation
Initialize the minimum frequency from the first word:
min_freq = Counter(words[0])For each following word, reduce counts to the minimum:
for ch in min_freq:
min_freq[ch] = min(min_freq[ch], word_freq.get(ch, 0))If a character from words[0] does not appear in a later word, its count drops to 0.
Expand the final counts into a list:
result.extend([ch] * count)Testing
def run_tests():
s = Solution()
assert sorted(s.commonChars(["bella", "label", "roller"])) == sorted(["e", "l", "l"])
assert sorted(s.commonChars(["cool", "lock", "cook"])) == sorted(["c", "o"])
assert sorted(s.commonChars(["abc", "abc"])) == sorted(["a", "b", "c"])
assert s.commonChars(["a", "b"]) == []
print("all tests passed")
run_tests()| Test | Expected | Why |
|---|---|---|
["bella","label","roller"] | ["e","l","l"] | Standard example |
["cool","lock","cook"] | ["c","o"] | Standard example |
["abc","abc"] | ["a","b","c"] | Identical words |
["a","b"] | [] | No characters in common |