0x01.问题
我们给出两个单词数组
A
和B
。每个单词都是一串小写字母。
现在,如果b
中的每个字母都出现在a
中,包括重复出现的字母,那么称单词b
是单词a
的子集。 例如,“wrr” 是 “warrior” 的子集,但不是 “world” 的子集。
如果对B
中的每一个单词b
,b
都是a
的子集,那么我们称A
中的单词a
是通用的。
你可以按任意顺序以列表形式返回 A 中所有的通用单词。
输入示例:A = [“amazon”,“apple”,“facebook”,“google”,“leetcode”], B = [“ec”,“oc”,“ceo”]
输出示例:[“facebook”,“leetcode”]
提示:
A[i]
和B[i]
只由小写字母组成。
A[i]
中所有的单词都是独一无二的,也就是说不存在i != j
使得A[i] == A[j]
。
1 <= A.length, B.length <= 10000
C++ 函数形式为:vector<string> wordSubsets(vector<string>& A, vector<string>& B)
此题来源于leetcode
0x02.分析问题
查找单词问题,首选仿造的哈希表,只需要对A的每个单词,在B中遍历所有的单词,看是否满足就行了。
0x03.最初代码
class Solution {
public:
vector<string> wordSubsets(vector<string>& A, vector<string>& B) {
vector<string> result;
int i,j,k,h;
for(i=0;i<A.size();i++){
vector<int>table(26,0);
for(j=0;j<A[i].size();j++){
table[A[i][j]-'a']++;
}
for(k=0;k<B.size();k++){
vector<int>Table(table);
for(h=0;h<B[k].size();h++){
if(Table[B[k][h]-'a']>=1){
Table[B[k][h]-'a']--;
}
else break;
}
if(h==B[k].size()) continue;
else break;
}
if(k==B.size()) result.push_back(A[i]);
else continue;
}
return result;
}
};
这段代码并没有错误,但是实在是太暴力了,因为已经达到O(N^3)
了,当然没有通过。
于是思考怎么优化。。。。。。
首先想得是怎么把这个三层循环变成二层循环,二层肯定是必须得,因为必须遍历到A中得所有单词嘛,所有目光就投向了B数组。
题目的意思是如果B中每个单词都是A中一个单词的子集的话,那么A中的那个单词就算是一个通用单词,所有我们可以找办法一次性,将B中的单词合起来,何A中的一个单词比较。
因为上面暴力比较的核心就是每个单词出现的次数,所以我们组合起来的那个B单词,应该包含每个小单词中字符出现次数最高的那个字符。
这个在B中小单词中出现次数最高的字符就是特征字符,因为只要单词中这个字符的数量都匹配了,那么其余小单词肯定是匹配的。
这种思想,叫做特征思想。
这样我们就可以把一个内存的循环转变为外层的循环,而且因为每个单词的字符都小于10,所以可以忽略不计,时间复杂度接近 O(N)
。
0x04.最终解决代码
class Solution {
public:
vector<string> wordSubsets(vector<string>& A, vector<string>& B) {
vector<string> result;
int i, j, k, h, m;
vector<int> tableb(26, 0);
for (k = 0; k < B.size(); k++) {
vector<int> tablebtemp(26, 0);
for (h = 0; h < B[k].size(); h++) {
tablebtemp[B[k][h] - 'a']++;
}
for (m = 0; m < 26; m++) {
tableb[m] = max(tableb[m], tablebtemp[m]);
}
}
for (i = 0; i < A.size(); i++) {
vector<int>tablea(26, 0);
for (j = 0; j < A[i].size(); j++) {
tablea[A[i][j] - 'a']++;
}
for (m = 0; m < 26; m++) {
if (tablea[m] >= tableb[m]) continue;
else break;
}
if (m == 26) result.push_back(A[i]);
}
return result;
}
};
ATFWUS --Writing By 2020–03–18