Find Words That Can Be Formed by Characters - Complete Solution Guide
Find Words That Can Be Formed by Characters is LeetCode problem 1160, a Easy level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
You are given an array of strings words and a string chars . A string is good if it can be formed by characters from chars (each character can only be used once for each word in words ). Return the sum of lengths of all good strings in words . Example 1: Input: words = ["cat","bt","hat","tree"], chars = "atach" Output: 6 Explanation: The strings that can be formed are "cat" and "hat" so the answer is 3 + 3 = 6. Example 2: Input: words = ["hello","world","leetcode"], chars = "welldonehoneyr" Outp
Detailed Explanation
This problem asks us to sift through a list of `words` and identify which ones can be 'formed' using the characters available in a separate string, `chars`. A word is considered 'good' if we can spell it out entirely using characters from `chars`. The critical detail here is that each character from `chars` can only be utilized once *per word*. This isn't a global depletion scenario; if `chars` has two 'a's, both 'cat' and 'hat' could potentially use an 'a' without 'cat' exhausting the 'a' supply for 'hat'. We ultimately need to sum up the lengths of all such 'good' words.
Solution Approach
The most intuitive and efficient way to handle character availability and usage is through frequency counting. The provided solution first builds a comprehensive frequency map, `char_counts`, for the `chars` string. This map acts as our 'budget' – it tells us exactly how many of each character we have at our disposal. Then, for each `word` in the `words` array, the solution performs a character-by-character check. It constructs a temporary frequency map, `word_counts`, for the *current* word. As it processes each character in the word, it immediately compares the character's count in `word_counts` against its available count in `char_counts`. If a character is either not present in `chars` at all, or the current word requires more of that character than `chars` provides, we know this word cannot be formed. In such cases, a flag `is_good` is set to `False`, and we efficiently break out of the inner loop, moving to the next word. If the word is fully processed and `is_good` remains `True`, it means we successfully 'budgeted' all its characters, and its length is added to our `total_length` sum.
Step-by-Step Algorithm
- Create a frequency map (dictionary in Python, array in Java/C/C++) to store the counts of each character in the input string `chars`.
- Iterate through each word in the `words` array.
- For each word, create a frequency map of its characters.
- Compare the word's character frequencies with the frequencies in `chars`. If any character in the word has a higher frequency than in `chars`, mark the word as 'bad' and proceed to the next word.
- If a word is deemed 'good', add its length to the `total_length`.
- Return the final `total_length`.
Key Insights
- **Frequency Mapping for Availability:** The core of solving this problem lies in accurately tracking character counts. By first creating a frequency map of `chars`, we establish a clear 'budget' of available characters. This allows for quick, O(1) lookups to determine if a character exists and in what quantity.
- **Per-Word Character Usage:** A crucial understanding is that the character availability from `chars` 'resets' for each word. This means we aren't cumulatively depleting `chars` across the entire `words` array. Our comparison for each word should always be against the *original* `char_counts` derived from `chars`, effectively granting each word a fresh pool of characters.
- **Early Exit Optimization:** For any given `word`, as soon as we encounter a character that isn't available in `chars` or is needed in a quantity greater than what `chars` provides, we know immediately that the word cannot be formed. There's no need to continue checking the rest of that `word`'s characters. Breaking out of the inner loop early significantly improves efficiency, especially for longer words that are quickly found to be 'not good'.
Complexity Analysis
Time Complexity: O(n*k)
Space Complexity: O(1)
Topics
This problem involves: Array, Hash Table, String, Counting.
Companies
Asked at: Atlassian, Datadog, Karat.