You are given a string allowed
consisting of distinct characters and an array of strings words
. A string is consistent if all characters in the string appear in the string allowed
.
Return the number of consistent strings in the array words
.
Example 1:
Input: allowed = "ab", words = ["ad","bd","aaab","baa","badab"] Output: 2 Explanation: Strings "aaab" and "baa" are consistent since they only contain characters 'a' and 'b'.
Example 2:
Input: allowed = "abc", words = ["a","b","c","ab","ac","bc","abc"] Output: 7 Explanation: All strings are consistent.
Example 3:
Input: allowed = "cad", words = ["cc","acd","b","ba","bac","bad","ac","d"] Output: 4 Explanation: Strings "cc", "acd", "ac", and "d" are consistent.
Constraints:
1 <= words.length <= 104
1 <= allowed.length <= 26
1 <= words[i].length <= 10
allowed
are distinct.words[i]
and allowed
contain only lowercase English letters.This problem asks us to count the number of strings in a given array words
that are "consistent" with a given string allowed
. A string is consistent if all its characters are present in the allowed
string.
We can solve this problem using two main approaches:
1. Hash Table (or Set) Approach:
This is a more straightforward approach. We first create a set (or hash table) containing all the characters in the allowed
string. This allows for O(1) lookup time to check if a character exists in allowed
. Then, we iterate through each string in words
. For each string, we iterate through its characters, checking if each character is present in our set. If all characters are present, we increment a counter.
Time Complexity: O(m), where m is the total number of characters across all strings in words
. This is because we iterate through the allowed
string once to build the set, and then we iterate through all the characters in the words
array.
Space Complexity: O(k), where k is the number of unique characters in allowed
. This is the space used to store the set. In the worst case, k could be 26 (all lowercase English letters).
Code Implementation (Python):
class Solution:
def countConsistentStrings(self, allowed: str, words: List[str]) -> int:
allowed_set = set(allowed)
count = 0
for word in words:
is_consistent = True
for char in word:
if char not in allowed_set:
is_consistent = False
break
if is_consistent:
count += 1
return count
2. Bit Manipulation Approach:
This approach is more concise and potentially faster for large inputs. We represent the characters in allowed
and each word as bitmasks. Each bit in the bitmask represents a letter of the alphabet (a=0, b=1, ... z=25). A bit is set to 1 if the corresponding letter is present in the string, and 0 otherwise.
We create a bitmask for allowed
. Then, for each word in words
, we create its bitmask. A word is consistent if its bitmask is a subset of the allowed
bitmask (meaning all its set bits are also set in the allowed
bitmask). We can check this using a bitwise AND operation. If word_mask & allowed_mask == word_mask
, the word is consistent.
Time Complexity: O(m), where m is the total number of characters in words
. We iterate through each character once to build the bitmask.
Space Complexity: O(1). We use a constant amount of extra space to store the bitmasks.
Code Implementation (Python):
class Solution:
def countConsistentStrings(self, allowed: str, words: List[str]) -> int:
allowed_mask = 0
for char in allowed:
allowed_mask |= (1 << (ord(char) - ord('a')))
count = 0
for word in words:
word_mask = 0
for char in word:
word_mask |= (1 << (ord(char) - ord('a')))
if (word_mask & allowed_mask) == word_mask:
count += 1
return count
Both approaches have the same time complexity, but the bit manipulation approach might offer a slight performance advantage due to its efficient bitwise operations. The hash table approach is generally easier to understand and implement. The choice between the two depends on your priorities (readability vs. potential performance gain). The provided solutions earlier contain implementations in various languages reflecting both approaches.