给你一个由不同字符组成的字符串 allowed
和一个字符串数组 words
。如果一个字符串的每一个字符都在 allowed
中,就称这个字符串是 一致字符串 。
请你返回 words
数组中 一致字符串 的数目。
示例 1:
输入:allowed = "ab", words = ["ad","bd","aaab","baa","badab"] 输出:2 解释:字符串 "aaab" 和 "baa" 都是一致字符串,因为它们只包含字符 'a' 和 'b' 。
示例 2:
输入:allowed = "abc", words = ["a","b","c","ab","ac","bc","abc"] 输出:7 解释:所有字符串都是一致的。
示例 3:
输入:allowed = "cad", words = ["cc","acd","b","ba","bac","bad","ac","d"] 输出:4 解释:字符串 "cc","acd","ac" 和 "d" 是一致字符串。
提示:
1 <= words.length <= 104
1 <= allowed.length <= 26
1 <= words[i].length <= 10
allowed
中的字符 互不相同 。words[i]
和allowed
只包含小写英文字母。
方法一:哈希表或数组
一种比较直接的思路是,用哈希表或数组 allowed
中的字符。然后遍历 words
数组,对于每个字符串 allowed
中的字符组成。若是,答案加一。
时间复杂度 allowed
字符集的大小。本题中
方法二:位运算
我们也可以仅用一个整数来表示每个字符串中字符的出现情况。其中,整数的二进制表示中的每一位表示一个字符是否出现。
我们简单地定义一个函数 ab
可以转换为整数 abd
可以转换为整数
回到题目上,判断一个字符串 allowed
中的字符组成,就可以转换为:判断
时间复杂度
class Solution:
def countConsistentStrings(self, allowed: str, words: List[str]) -> int:
s = set(allowed)
return sum(all(c in s for c in w) for w in words)
class Solution:
def countConsistentStrings(self, allowed: str, words: List[str]) -> int:
def f(w):
return reduce(or_, (1 << (ord(c) - ord('a')) for c in w))
mask = f(allowed)
return sum((mask | f(w)) == mask for w in words)
class Solution {
public int countConsistentStrings(String allowed, String[] words) {
boolean[] s = new boolean[26];
for (char c : allowed.toCharArray()) {
s[c - 'a'] = true;
}
int ans = 0;
for (String w : words) {
if (check(w, s)) {
++ans;
}
}
return ans;
}
private boolean check(String w, boolean[] s) {
for (int i = 0; i < w.length(); ++i) {
if (!s[w.charAt(i) - 'a']) {
return false;
}
}
return true;
}
}
class Solution {
public int countConsistentStrings(String allowed, String[] words) {
int mask = f(allowed);
int ans = 0;
for (String w : words) {
if ((mask | f(w)) == mask) {
++ans;
}
}
return ans;
}
private int f(String w) {
int mask = 0;
for (int i = 0; i < w.length(); ++i) {
mask |= 1 << (w.charAt(i) - 'a');
}
return mask;
}
}
class Solution {
public:
int countConsistentStrings(string allowed, vector<string>& words) {
bitset<26> s;
for (auto& c : allowed) s[c - 'a'] = 1;
int ans = 0;
auto check = [&](string& w) {
for (auto& c : w) if (!s[c - 'a']) return false;
return true;
};
for (auto& w : words) ans += check(w);
return ans;
}
};
class Solution {
public:
int countConsistentStrings(string allowed, vector<string>& words) {
auto f = [](string& w) {
int mask = 0;
for (auto& c : w) mask |= 1 << (c - 'a');
return mask;
};
int mask = f(allowed);
int ans = 0;
for (auto& w : words) ans += (mask | f(w)) == mask;
return ans;
}
};
func countConsistentStrings(allowed string, words []string) (ans int) {
s := [26]bool{}
for _, c := range allowed {
s[c-'a'] = true
}
check := func(w string) bool {
for _, c := range w {
if !s[c-'a'] {
return false
}
}
return true
}
for _, w := range words {
if check(w) {
ans++
}
}
return ans
}
func countConsistentStrings(allowed string, words []string) (ans int) {
f := func(w string) (mask int) {
for _, c := range w {
mask |= 1 << (c - 'a')
}
return
}
mask := f(allowed)
for _, w := range words {
if (mask | f(w)) == mask {
ans++
}
}
return
}
int countConsistentStrings(char *allowed, char **words, int wordsSize) {
int n = strlen(allowed);
int make[26] = {0};
for (int i = 0; i < n; i++) {
make[allowed[i] - 'a'] = 1;
}
int ans = wordsSize;
for (int i = 0; i < wordsSize; i++) {
char *word = words[i];
for (int j = 0; j < strlen(word); j++) {
if (!make[word[j] - 'a']) {
ans--;
break;
}
}
}
return ans;
}
int helper(char *s) {
int res = 0;
int n = strlen(s);
for (int i = 0; i < n; i++) {
res |= 1 << (s[i] - 'a');
}
return res;
}
int countConsistentStrings(char *allowed, char **words, int wordsSize) {
int mask = helper(allowed);
int ans = 0;
for (int i = 0; i < wordsSize; i++) {
if ((mask | helper(words[i])) == mask) {
ans++;
}
}
return ans;
}
function countConsistentStrings(allowed: string, words: string[]): number {
const set = new Set([...allowed]);
const n = words.length;
let ans = n;
for (const word of words) {
for (const c of word) {
if (!set.has(c)) {
ans--;
break;
}
}
}
return ans;
}
function countConsistentStrings(allowed: string, words: string[]): number {
const helper = (s: string) => {
let res = 0;
for (const c of s) {
res |= 1 << (c.charCodeAt(0) - 'a'.charCodeAt(0));
}
return res;
};
const mask = helper(allowed);
let ans = 0;
for (const word of words) {
if ((mask | helper(word)) === mask) {
ans++;
}
}
return ans;
}
impl Solution {
pub fn count_consistent_strings(allowed: String, words: Vec<String>) -> i32 {
let n = words.len();
let mut make = [false; 26];
for c in allowed.as_bytes() {
make[(c - b'a') as usize] = true;
}
let mut ans = n as i32;
for word in words.iter() {
for c in word.as_bytes().iter() {
if !make[(c - b'a') as usize] {
ans -= 1;
break;
}
}
}
ans
}
}
impl Solution {
fn helper(s: &String) -> i32 {
let mut res = 0;
for c in s.as_bytes().iter() {
res |= 1 << (c - b'a') as i32;
}
res
}
pub fn count_consistent_strings(allowed: String, words: Vec<String>) -> i32 {
let mask = Self::helper(&allowed);
let mut ans = 0;
for word in words.iter() {
if (mask | Self::helper(word)) == mask {
ans += 1;
}
}
ans
}
}