
Problem Statement
You are provided with two inputs:
- A string named
allowedwhich comprises distinct lowercase English characters. - An array of strings called
words.
In this context, a string from the array words is termed consistent if every character within that string can be found in the allowed string.
The task is to determine and return the number of consistent strings within the provided array words. This problem taps into string manipulation and character checking processes comprehensively.
Examples
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 <= 1041 <= allowed.length <= 261 <= words[i].length <= 10- The characters in
allowedare distinct. words[i]andallowedcontain only lowercase English letters.
Approach and Intuition
The main goal of this problem is to evaluate each string in the words array and check if all of its characters are present in the allowed string to classify it as consistent. To achieve this efficiently, follow these steps:
Convert the
allowedstring into a set of characters. This conversion provides O(1) complexity for character lookup, making it much faster than checking each character's existence by iterating through theallowedstring.Initialize a counter to track the number of consistent strings.
Go over each word in the
wordsarray and check if every character is in the set we created fromallowed. If a character is found that’s not in theallowedset, you can conclude this word is inconsistent and skip to the next word.For each word that passes the character check, increment your consistency counter.
Finally, after all words are processed, return the count of consistent strings.
Here are some additional insights into the approach:
- Using a set for the
allowedcharacters optimizes the character lookup process, which is crucial because character checking is the central operation of the solution. - Looping through each word and then through each character might seem like a nested operation, but both operations are relatively short due to constraints (maximum of 10 characters per word and 26 allowed characters).
- The count sequence when a character isn’t allowed in a word stops further unnecessary checks on that word, enhancing efficiency.
By following these guided steps, the given problem can be tackled to determine and count all consistent strings against the allowed characters effectively.
Solutions
- C++
- Java
- Python
class Solution {
public:
int countValidStrings(string allowedChars, vector<string>& wordList) {
// allowedMask will store the bitmask of allowed characters
int allowedMask = 0;
// Initialize bitmask for allowed characters
for (char ch : allowedChars) {
allowedMask |= 1 << (ch - 'a');
}
int validCount = 0;
// Check all words in the wordList
for (const string& word : wordList) {
bool isValid = true;
// Check each character's validity in the word
for (char c : word) {
// Mask for the current character
int currentCharMask = (allowedMask >> (c - 'a')) & 1;
// If this character is not allowed
if (currentCharMask == 0) {
isValid = false;
break;
}
}
// Increment the count if word is valid
if (isValid) {
validCount++;
}
}
return validCount;
}
};
This solution defines a function countValidStrings to determine the number of strings in a provided list (wordList) that consist only of characters found in a specified allowedChars string. The function efficiently handles this task through the utilization of bit manipulation strategies. Below summarizes the implementation steps in C++:
Initialize an integer
allowedMaskto store a bitmask representing the characters allowed for valid strings. This bitmask is created by iterating over each character inallowedCharsand setting the corresponding bit.Iterate through each word in
wordListand determine its validity againstallowedMask:- For each word, check each character to see if it exists in the
allowedMask. This is achieved by shifting theallowedMaskright by the alphabetical index of the character and checking the least significant bit. - If a character in the word is not present in the
allowedMask, mark the word as invalid and break out of the checking loop.
- For each word, check each character to see if it exists in the
If a word passes the character check, increment the count of valid words.
Finally, the function returns the total count of valid words.
The implementation leverages the efficiency of bitwise operations to check character inclusion, making the solution optimal for large input sizes.
class Solution {
public int countAllowedStrings(String allowedChars, String[] wordList) {
int allowedMask = 0;
for (int i = 0; i < allowedChars.length(); i++) {
allowedMask |= 1 << (allowedChars.charAt(i) - 'a');
}
int count = 0;
for (String word : wordList) {
boolean isAllowed = true;
for (int i = 0; i < word.length(); i++) {
int currentBit = (allowedMask >> (word.charAt(i) - 'a')) & 1;
if (currentBit == 0) {
isAllowed = false;
break;
}
}
if (isAllowed) {
count++;
}
}
return count;
}
}
This Java program defines a method named countAllowedStrings aimed at determining how many strings within an array (wordList) consist solely of characters defined in the allowedChars string. The solution applies bit manipulation techniques to optimize the process of checking if each character in a word from the wordList is included in the allowedChars.
- Start by initializing an integer
allowedMaskto zero. This integer will use its bits to flag which characters are permitted. - Iterate over each character in the
allowedCharsstring:- Update
allowedMaskby setting the bit corresponding to each character. This is achieved by shifting the bit to the left according to the character's position in the alphabet.
- Update
- Initialize a counter
countto keep track of how many strings fromwordListare composed only of allowed characters. - Iterate over each string in the
wordList:- Assume initially that the string is allowed (
isAllowedset to true). - For each character in the current word, determine its respective bit in
allowedMaskto check if the character is allowed:- If any character in the word has its corresponding bit not set in
allowedMask, markisAllowedas false and exit the inner loop.
- If any character in the word has its corresponding bit not set in
- If, after checking every character, the word is still marked as allowed, increase the
countby one.
- Assume initially that the string is allowed (
The method finally returns the count of consistent strings, which are those composed entirely of allowed characters. This approach reduces the time complexity compared to brute force methods, especially beneficial as the size of the input increases.
class Solution:
def countValidWords(self, allowed_chars: str, word_list: List[str]) -> int:
permitted_bits = 0
for char in allowed_chars:
permitted_bits |= 1 << (ord(char) - ord('a'))
valid_count = 0
for word in word_list:
passes_check = True
for char in word:
character_bit = (permitted_bits >> (ord(char) - ord('a'))) & 1
if character_bit == 0:
passes_check = False
break
if passes_check:
valid_count += 1
return valid_count
In the given problem, the Python function countValidWords solves the task of counting how many strings in a list (word_list) consist only of characters in a specified set (allowed_chars). This is effectively an application of bit manipulation to efficiently check character permissions against a given set of allowed characters.
Here’s how the provided solution works:
Initially, the function defines an integer
permitted_bitsrepresenting binary flags for each character. A1at any bit position inpermitted_bitsindicates that the corresponding character is allowed.The function iterates through each character in
allowed_chars, setting the corresponding bit inpermitted_bitsbased on the ASCII value of the character minus the ASCII value of'a'(i.e., for 'a' it sets bit position 0, for 'b' it sets bit position 1, and so forth).After constructing the
permitted_bits, the function initializes a countervalid_countto zero. This counter tallies the number of valid strings from theword_listthat are completely composed of allowed characters.For each word in
word_list, it checks all characters in the word to ensure they are allowed by shifting thepermitted_bitsaccording to the character's position and checking the least significant bit. If it finds any character that is not allowed, it setspasses_checktoFalse, and the loop breaks, moving to the next word.If all characters in a word meet the allowed criteria (
passes_checkremainsTrue), the function increments thevalid_count.The function ends by returning
valid_count, which represents the number of words inword_listthat consist solely of characters fromallowed_chars.
This approach greatly optimizes the task by using bit manipulation, reducing the complexity and the need for multiple nested loop checks against the allowed_chars for every character in every word.