问题
我们有两个数组A和B的单词。每个单词都是一串小写字母。现在,假设单词b是单词a的子集如果b中的每个字母都出现在a中,并且可以出现多次。例如,“wrr”是“warrior”的子集,但不是“world”的子集。现在说一个来自a的词a是普遍的如果对于b中的每一个b, b是a的子集。返回a中所有通用单词的列表。这些单词的顺序可以是任意的。
解析
题目很直观,同样我们给出一个更加直观的解法。我们先将字符串数组B中出现的所有字符保存下来,并记录次数(注意,字符串内的相同字符计数,字符串间的相同字符取最大值)。然后和A数组中的字符串逐一对比(遍历一次),如果字符串的字符出现次数小于我们记录的次数,那么该字符串就不符合要求。并且时间复杂度为 O ( m + n ) O(m+n) O(m+n),其中m,n分别为两个字符串数组的长度。
Java代码
public List<String> wordSubsets(String[] A, String[] B) {
int countsB[] = new int[26];
for(int i=0;i<B[0].length();i++){
countsB[B[0].charAt(i)-'a']++;
}
for(int i=0;i<B.length;i++){
int temp[] = new int[26];
for(char c:B[i].toCharArray()){
temp[c-'a']++;
countsB[c-'a']=Math.max(countsB[c-'a'],temp[c-'a']);
}
}
List<String> list = new ArrayList();
for(int i=0;i<A.length;i++){
int temp[] = new int[26];
boolean flag = true;
for(char c:A[i].toCharArray()){
temp[c-'a']++;
}
for(int j=0;j<26;j++){
if(temp[j]<countsB[j]) {
flag =false;
break;
}
}
if(flag){
list.add(A[i]);
}
}
return list;
}