
Problem Statement
You are provided with two inputs:
- A string named
allowed
which 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 <= 104
1 <= allowed.length <= 26
1 <= words[i].length <= 10
- The characters in
allowed
are distinct. words[i]
andallowed
contain 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
allowed
string 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 theallowed
string.Initialize a counter to track the number of consistent strings.
Go over each word in the
words
array and check if every character is in the set we created fromallowed
. If a character is found that’s not in theallowed
set, 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
allowed
characters 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
allowedMask
to store a bitmask representing the characters allowed for valid strings. This bitmask is created by iterating over each character inallowedChars
and setting the corresponding bit.Iterate through each word in
wordList
and determine its validity againstallowedMask
:- For each word, check each character to see if it exists in the
allowedMask
. This is achieved by shifting theallowedMask
right 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
allowedMask
to zero. This integer will use its bits to flag which characters are permitted. - Iterate over each character in the
allowedChars
string:- Update
allowedMask
by 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
count
to keep track of how many strings fromwordList
are composed only of allowed characters. - Iterate over each string in the
wordList
:- Assume initially that the string is allowed (
isAllowed
set to true). - For each character in the current word, determine its respective bit in
allowedMask
to check if the character is allowed:- If any character in the word has its corresponding bit not set in
allowedMask
, markisAllowed
as 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
count
by 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_bits
representing binary flags for each character. A1
at any bit position inpermitted_bits
indicates that the corresponding character is allowed.The function iterates through each character in
allowed_chars
, setting the corresponding bit inpermitted_bits
based 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_count
to zero. This counter tallies the number of valid strings from theword_list
that 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_bits
according to the character's position and checking the least significant bit. If it finds any character that is not allowed, it setspasses_check
toFalse
, and the loop breaks, moving to the next word.If all characters in a word meet the allowed criteria (
passes_check
remainsTrue
), the function increments thevalid_count
.The function ends by returning
valid_count
, which represents the number of words inword_list
that 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.
No comments yet.