Welcome to Subscribe On Youtube
Formatted question description: https://leetcode.ca/all/2135.html
2135. Count Words Obtained After Adding a Letter
- Difficulty: Medium.
- Related Topics: Array, Hash Table, String, Bit Manipulation, Sorting.
- Similar Questions: Strings Differ by One Character, Count Substrings That Differ by One Character, Maximum Score From Removing Substrings.
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"
.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.
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 * 104
-
1 <= startWords[i].length, targetWords[j].length <= 26
-
Each string of
startWords
andtargetWords
consists of lowercase English letters only. -
No letter occurs more than once in any string of
startWords
ortargetWords
.
Solution (Java, C++, Python)
-
class Solution { private Set<Integer> set; private void preprocess(String[] words) { set = new HashSet<>(); for (String word : words) { int bitMap = getBitMap(word); set.add(bitMap); } } private boolean matches(int bitMap) { return set.contains(bitMap); } private int getBitMap(String word) { int result = 0; for (int i = 0; i < word.length(); i++) { int position = word.charAt(i) - 'a'; result |= (1 << position); } return result; } private int addBit(int bitMap, char c) { int position = c - 'a'; bitMap |= (1 << position); return bitMap; } private int removeBit(int bitMap, char c) { int position = c - 'a'; bitMap &= ~(1 << position); return bitMap; } public int wordCount(String[] startWords, String[] targetWords) { if (startWords == null || startWords.length == 0) { return 0; } if (targetWords == null || targetWords.length == 0) { return 0; } preprocess(startWords); int count = 0; for (String word : targetWords) { int bitMap = getBitMap(word); for (int i = 0; i < word.length(); i++) { bitMap = removeBit(bitMap, word.charAt(i)); if (i > 0) { bitMap = addBit(bitMap, word.charAt(i - 1)); } if (matches(bitMap)) { count++; break; } } } return count; } } ############ class Solution { public int wordCount(String[] startWords, String[] targetWords) { Set<Integer> s = new HashSet<>(); for (String word : startWords) { int mask = 0; for (char c : word.toCharArray()) { mask |= (1 << (c - 'a')); } s.add(mask); } int ans = 0; for (String word : targetWords) { int mask = 0; for (char c : word.toCharArray()) { mask |= (1 << (c - 'a')); } for (char c : word.toCharArray()) { int t = mask ^ (1 << (c - 'a')); if (s.contains(t)) { ++ans; break; } } } return ans; } }
-
class Solution: def wordCount(self, startWords: List[str], targetWords: List[str]) -> int: s = set() for word in startWords: mask = 0 for c in word: mask |= 1 << (ord(c) - ord('a')) s.add(mask) ans = 0 for word in targetWords: mask = 0 for c in word: mask |= 1 << (ord(c) - ord('a')) for c in word: t = mask ^ (1 << (ord(c) - ord('a'))) if t in s: ans += 1 break return ans ############ # 2135. Count Words Obtained After Adding a Letter # https://leetcode.com/problems/count-words-obtained-after-adding-a-letter class Solution: def wordCount(self, startWords: List[str], targetWords: List[str]) -> int: targets = Counter() def construct(words): mask = 0 for x in words: mask |= (1 << ord(x) - ord('a')) return mask for words in targetWords: mask = construct(words) targets[mask] += 1 res = 0 for words in startWords: currMask = construct(words) for i in range(26): if currMask & (1 << i) > 0: continue newMask = currMask | (1 << i) if newMask in targets: res += targets[newMask] del targets[newMask] return res
-
class Solution { public: int wordCount(vector<string>& startWords, vector<string>& targetWords) { unordered_set<int> s; for (auto& word : startWords) { int mask = 0; for (char c : word) mask |= (1 << (c - 'a')); s.insert(mask); } int ans = 0; for (auto& word : targetWords) { int mask = 0; for (char c : word) mask |= (1 << (c - 'a')); for (char c : word) { int t = mask ^ (1 << (c - 'a')); if (s.count(t)) { ++ans; break; } } } return ans; } };
-
func wordCount(startWords []string, targetWords []string) int { s := make(map[int]bool) for _, word := range startWords { mask := 0 for _, c := range word { mask |= (1 << (c - 'a')) } s[mask] = true } ans := 0 for _, word := range targetWords { mask := 0 for _, c := range word { mask |= (1 << (c - 'a')) } for _, c := range word { t := mask ^ (1 << (c - 'a')) if s[t] { ans++ break } } } return ans }
Explain:
nope.
Complexity:
- Time complexity : O(n).
- Space complexity : O(n).