Count Words Obtained After Adding a Letter solution and explanation
9 more videos on this problem
Count Words Obtained After Adding a Letter | Leetcode 2135 | Contest 275 |String | Bit Masking 🔥🔥🔥Coding Decoded · 11:40 · 1K views
Count Words obtained after adding a letter || LeetCode 2135 || Weekly LeetCode-275 || C++Bro Coders · 9:29 · 1K views
COUNT WORDS OBTAINED AFTER ADDING A LETTER | LEETCODE # 2135 | PYTHON SOLUTIONCracking FAANG · 7:10 · 1K views
Count Words Obtained After Adding a Letter | LeetCode 2135 | LeetCode Weekly 275 | Java HindiPepcoding · 54:20 · 770 views
2135. Count Words Obtained After Adding a Letter (Leetcode Medium)Programming Live with Larry · 15:00 · 730 views
Count Words Obtained After Adding a Letter | Weekly Contest 275 | LeetCodeWe are Coders · 5:25 · 564 views
2135. Count Words Obtained after Adding a Letter (Leetcode Problem)viralSongs · 3:37 · 254 views
Leetcode - 2135 Count Words Obtained After Adding a Letter - Logic Explained With ExamplesAlgorithmicIQ · 21:28 · 203 views
Leetcode 2135. Count Words Obtainer After Adding a Letter 中文bbbb · 8:20 · 116 views
讲解2135. Count Words Obtained After Adding a LetterHaoyang Chen · 19:53 · 47 views
The problem
You are given two 0-indexed arrays of strings startWords and targetWords. Each string consists of lowercase English letters only.
For each string in targetWords, check if it is possible to choose a string from startWords and perform a conversion operation on it to be equal to that from targetWords.
The conversion operation is described in the following two steps:
- Append any lowercase letter that is not present in the string to its end.
- For example, if the string is
"abc", the letters'd','e', or'y'can be added to it, but not'a'. If'd'is added, the resulting string will be"abcd".
- For example, if the string is
- Rearrange the letters of the new string in any arbitrary order.
- For example,
"abcd"can be rearranged to"acbd","bacd","cbda", and so on. Note that it can also be rearranged to"abcd"itself.
- For example,
Return the number of strings in targetWords that can be obtained by performing the operations on any string of startWords.
Note that you will only be verifying if the string in targetWords can be obtained from a string in startWords by performing the operations. The strings in startWords do not actually change during this process.
Example 1:
Input: startWords = ["ant","act","tack"], targetWords = ["tack","act","acti"] Output: 2 Explanation: - In order to form targetWords[0] = "tack", we use startWords[1] = "act", append 'k' to it, and rearrange "actk" to "tack". - There is no string in startWords that can be used to obtain targetWords[1] = "act". Note that "act" does exist in startWords, but we must append one letter to the string before rearranging it. - In order to form targetWords[2] = "acti", we use startWords[1] = "act", append 'i' to it, and rearrange "acti" to "acti" itself.
Example 2:
Input: startWords = ["ab","a"], targetWords = ["abc","abcd"] Output: 1 Explanation: - In order to form targetWords[0] = "abc", we use startWords[0] = "ab", add 'c' to it, and rearrange it to "abc". - There is no string in startWords that can be used to obtain targetWords[1] = "abcd".
Constraints:
1 <= startWords.length, targetWords.length <= 5 * 1041 <= startWords[i].length, targetWords[j].length <= 26- Each string of
startWordsandtargetWordsconsists of lowercase English letters only. - No letter occurs more than once in any string of
startWordsortargetWords.
Approach overview
Problem Overview: You receive two arrays: startWords and targetWords. A target word is valid if you can take a word from startWords, add exactly one letter, and then rearrange the characters to match the target. The task is to count how many target words can be produced this way.
Approach 1: Set of Sorted Signatures (O(S * k log k + T * k^2 log k) time, O(S * k) space)
This approach normalizes words using sorted character signatures. For every word in startWords, sort its characters and store the result in a set for O(1) membership checks. For each word in targetWords, remove one character at every index, sort the remaining characters, and check whether the resulting signature exists in the set. If any removal matches a stored start signature, the target word is achievable.
The key idea: rearranging characters means only the multiset of letters matters. Sorting converts every word into a canonical representation. The set lookup avoids scanning the entire start list. This solution relies on sorting and a hash table for efficient lookups.
Approach 2: Bitmask Representation (O((S + T) * 26) time, O(S) space)
A more efficient technique encodes each word as a 26-bit integer mask where bit i represents whether letter 'a' + i appears. Build a hash set of masks for all startWords. For every targetWord, compute its mask, then try removing each set bit (simulating the removal of the added letter). If the resulting mask exists in the start set, the target word can be formed.
This works because each letter appears at most once in valid transformations. Bit operations make checking subsets extremely fast. Instead of sorting strings repeatedly, you perform constant-time bit manipulations and hash lookups. The method combines bit manipulation with a hash table, reducing the complexity to roughly linear in the number of words.
Recommended for interviews: The bitmask approach is the expected optimal solution. It demonstrates strong understanding of character encoding and efficient set membership checks. The sorted-signature approach is still valuable during interviews because it shows clear reasoning about normalization and hashing before optimizing further.
Approach 1: Set of Sorted Signatures
Transform each word in startWords into a sorted tuple of its characters to leverage the properties of sorted words. This forms a distinct signature that can be stored in a set for quick lookup. For each word in targetWords, remove one character at a time, sort the remaining characters, and check if this signature exists in the startWords set.
def count_obtained_words(startWords, targetWords):
def sorted_tuple(word):
return tuple(sorted(word))
# Create a set of sorted character tuples for startWords
startSet = {sorted_tuple(word) for word in startWords}
count = 0
for target in targetWords:
for i in range(len(target)):
# Remove the character at i and sort the remaining
signature = sorted_tuple(target[:i] + target[i+1:])
if signature in startSet:
count += 1
break
return count#include <iostream>
#include <vector>
#include <unordered_set>
#include <string>
#include <algorithm>
std::string get_sorted_signature(const std::string& word) {
std::string sortedWord = word;
std::sort(sortedWord.begin(), sortedWord.end());
return sortedWord;
}
int count_obtained_words(std::vector<std::string>& startWords, std::vector<std::string>& targetWords) {
std::unordered_set<std::string> startSet;
for (const auto& word : startWords) {
startSet.insert(get_sorted_signature(word));
}
int count = 0;
for (const auto& target : targetWords) {
for (size_t i = 0; i < target.size(); ++i) {
std::string modifiedTarget = target;
modifiedTarget.erase(modifiedTarget.begin() + i);
if (startSet.count(get_sorted_signature(modifiedTarget))) {
++count;
break;
}
}
}
return count;
}This function creates a unique signature for each word by sorting its characters. A set is populated with these signatures for the startWords. The function then iterates through each targetWords word, removing one character at a time, sorting the rest, and checking if this reduced form exists in startSet. The count is incremented for each match found.
Time Complexity: O(NM log M + KM log M), where N is the length of startWords, K is the length of targetWords, M is the maximum word length.
Space Complexity: O(NM), for storing the sorted signatures.
Approach 2: Bitmask Representation
Each character in a word can be represented as a bit in an integer (26 bits for 26 letters). Convert each word into a bitmask representation where each bit denotes the presence of a character. Check if removing one bit from any targetWords bitmask results in a startWords bitmask.
import java.util.HashSet;
class Solution {
private int getBitmask(String word) {
int bitmask = 0;
for (char ch : word.toCharArray()) {
bitmask |= 1 << (ch - 'a');
}
return bitmask;
}
public int countObtainedWords(String[] startWords, String[] targetWords) {
HashSet<Integer> startSet = new HashSet<>();
for (String word : startWords) {
startSet.add(getBitmask(word));
}
int count = 0;
for (String target : targetWords) {
int targetBitmask = getBitmask(target);
for (char ch : target.toCharArray()) {
int newBitmask = targetBitmask ^ (1 << (ch - 'a'));
if (startSet.contains(newBitmask)) {
count++;
break;
}
}
}
return count;
}
}function countObtainedWords(startWords, targetWords) {
const getBitmask = (word) => {
let bitmask = 0;
for (let char of word) {
bitmask |= 1 << (char.charCodeAt(0) - 'a'.charCodeAt(0));
}
return bitmask;
};
const startSet = new Set();
for (let word of startWords) {
startSet.add(getBitmask(word));
}
let count = 0;
for (let target of targetWords) {
const targetBitmask = getBitmask(target);
for (let char of target) {
const newBitmask = targetBitmask ^ (1 << (char.charCodeAt(0) - 'a'.charCodeAt(0)));
if (startSet.has(newBitmask)) {
count++;
break;
}
}
}
return count;
}This Java solution uses bit manipulation to represent each word. The getBitmask method creates a bitmask for a word. The function then checks if modifying the bitmask of any targetWords by removing one character (one bit) results in an achievable startWords bitmask. If it exists in the start set of bitmasks, it increases the counter.
Time Complexity: O(NM + KM), where N and K are the sizes of startWords and targetWords, M is the maximum length of a word.
Space Complexity: O(N), for bitmask storage.
Approach 3: Hash Table + Bit Manipulation
We notice that the given strings only contain lowercase letters, and each letter in a string appears at most once. Therefore, we can represent a string with a binary number of length 26, where the i-th bit being 1 indicates that the string contains the i-th lowercase letter, and 0 indicates the absence of the i-th lowercase letter.
We can convert each string in the array startWords into a binary number and store these binary numbers in a set s. For each string in the array targetWords, we first convert it into a binary number, then enumerate each letter in this string, remove this letter from the binary number, and check if there exists a binary number in the set s such that the XOR result of this binary number with the removed letter's binary number is in the set s. If such a binary number exists, then this string can be obtained by performing a transformation operation on some string in startWords, and we increment the answer by one. Then, we skip this string and continue processing the next string.
The time complexity is O(n times |\Sigma|), and the space complexity is O(n). Here, n is the length of the string array targetWords, and |\Sigma| is the size of the character set in the string, which is 26 in this problem.
function wordCount(startWords: string[], targetWords: string[]): number {
const s = new Set<number>();
for (const w of startWords) {
let x = 0;
for (const c of w) {
x ^= 1 << (c.charCodeAt(0) - 97);
}
s.add(x);
}
let ans = 0;
for (const w of targetWords) {
let x = 0;
for (const c of w) {
x ^= 1 << (c.charCodeAt(0) - 97);
}
for (const c of w) {
if (s.has(x ^ (1 << (c.charCodeAt(0) - 97)))) {
++ans;
break;
}
}
}
return ans;
}func wordCount(startWords []string, targetWords []string) (ans int) {
s := map[int]bool{}
for _, w := range startWords {
x := 0
for _, c := range w {
x |= 1 << (c - 'a')
}
s[x] = true
}
for _, w := range targetWords {
x := 0
for _, c := range w {
x |= 1 << (c - 'a')
}
for _, c := range w {
if s[x^(1<<(c-'a'))] {
ans++
break
}
}
}
return
}Complexity comparison
| Approach | Complexity |
|---|---|
| Set of Sorted Signatures | Time Complexity: O(NM log M + KM log M), where N is the length of startWords, K is the length of targetWords, M is the maximum word length. |
| Bitmask Representation | Time Complexity: O(NM + KM), where N and K are the sizes of startWords and targetWords, M is the maximum length of a word. |
| Hash Table + Bit Manipulation | – |
Complexity analysis
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Set of Sorted Signatures | O(S * k log k + T * k^2 log k) | O(S * k) | When using straightforward string normalization and sorting is acceptable |
| Bitmask Representation | O((S + T) * 26) | O(S) | Preferred optimal approach for interviews and large inputs |
Frequently asked questions
Is Count Words Obtained After Adding a Letter easy or hard?
The problem is rated Medium on LeetCode with an acceptance rate around 44%. The challenge comes from recognizing that character order does not matter and converting the problem into a normalized representation such as sorted strings or bitmasks.
Count Words Obtained After Adding a Letter Python/Java solution
Python solutions commonly use sorted signatures with a set for simplicity, while Java implementations often prefer the bitmask approach for performance. Both methods rely on hash sets for constant-time lookups and iterate through each target word while removing one character or bit.
How to solve Count Words Obtained After Adding a Letter in O(n)?
Use a bitmask to represent the characters in each word. Insert masks of startWords into a hash set. For every target word, compute its mask and attempt removing each letter by clearing one bit. If any resulting mask exists in the set, the target word can be formed. This makes the algorithm close to linear with respect to the number of words.
What is the best approach for Count Words Obtained After Adding a Letter?
The most efficient approach uses bitmask representation. Each word is encoded as a 26-bit integer where each bit corresponds to a letter. Store masks for startWords in a hash set, then for each target word remove one bit at a time and check if the resulting mask exists. This reduces the problem to constant-time bit operations and hash lookups.
Is Count Words Obtained After Adding a Letter asked at Google/Amazon/Meta?
This problem represents a common interview pattern involving hashing, bit manipulation, and string normalization. Variants of this problem have appeared in interviews at companies like Google, Amazon, and Meta because they test efficient set lookups and bit-level optimizations.
What data structure is used in Count Words Obtained After Adding a Letter?
A hash set is the primary data structure used to store normalized representations of start words. Depending on the approach, the stored values are either sorted string signatures or integer bitmasks representing letter presence.
What is the time complexity of Count Words Obtained After Adding a Letter?
The optimal bitmask solution runs in O((S + T) * 26) time, where S is the number of start words and T is the number of target words. Each word requires building a mask and checking up to 26 possible bit removals. Space complexity is O(S) for storing the start word masks.
