We are given two arrays `A` and `B` of words. Each word is a string of lowercase letters.
Now, say that word b
is a subset of word a
if every letter in b
occurs in a
, including multiplicity. For example, "wrr"
is a subset of "warrior"
, but is not a subset of "world"
.
Now say a word a
from A
is universal if for every b
in B
, b
is a subset of a
.
Return a list of all universal words in A
. You can return the words in any order.
Example 1:
Input: A = ["amazon","apple","facebook","google","leetcode"], B = ["e","o"]
Output: ["facebook","google","leetcode"]
Example 2:
Input: A = ["amazon","apple","facebook","google","leetcode"], B = ["l","e"]
Output: ["apple","google","leetcode"]
Example 3:
Input: A = ["amazon","apple","facebook","google","leetcode"], B = ["e","oo"]
Output: ["facebook","google"]
Example 4:
Input: A = ["amazon","apple","facebook","google","leetcode"], B = ["lo","eo"]
Output: ["google","leetcode"]
Example 5:
Input: A = ["amazon","apple","facebook","google","leetcode"], B = ["ec","oc","ceo"]
Output: ["facebook","leetcode"]
Note:
1 <= A.length, B.length <= 10000
1 <= A[i].length, B[i].length <= 10
A[i]
andB[i]
consist only of lowercase letters.- All words in
A[i]
are unique: there isn'ti != j
withA[i] == A[j]
.
這道題定義了兩個單詞之間的一種子集合關系,就是說假如單詞b中的每個字母都在單詞a中出現了(包括重復字母),就說單詞b是單詞a的子集合。現在給了兩個單詞集合A和B,讓找出集合A中的所有滿足要求的單詞,使得集合B中的所有單詞都是其子集合。配合上題目中給的一堆例子,意思並不難理解,根據子集合的定義關系,其實就是說若單詞a中的每個字母的出現次數都大於等於單詞b中每個字母的出現次數,單詞b就一定是a的子集合。現在由於集合B中的所有單詞都必須是A中某個單詞的子集合,那么其實只要對於每個字母,都統計出集合B中某個單詞中出現的最大次數,比如對於這個例子,B=["eo","oo"],其中e最多出現1次,而o最多出現2次,那么只要集合A中有單詞的e出現不少1次,o出現不少於2次,則集合B中的所有單詞一定都是其子集合。這就是本題的解題思路,這里使用一個大小為 26 的一維數組 charCnt 來統計集合B中每個字母的最大出現次數,而將統計每個單詞的字母次數的操作放到一個子函數 helper 中,當 charCnt 數組更新完畢后,下面就開始檢驗集合A中的所有單詞了。對於每個遍歷到的單詞,還是要先統計其每個字母的出現次數,然后跟 charCnt 中每個位置上的數字比較,只要均大於等於 charCnt 中的數字,就可以加入到結果 res 中了,參見代碼如下:
class Solution {
public:
vector<string> wordSubsets(vector<string>& A, vector<string>& B) {
vector<string> res;
vector<int> charCnt(26);
for (string &b : B) {
vector<int> t = helper(b);
for (int i = 0; i < 26; ++i) {
charCnt[i] = max(charCnt[i], t[i]);
}
}
for (string &a : A) {
vector<int> t = helper(a);
int i = 0;
for (; i < 26; ++i) {
if (t[i] < charCnt[i]) break;
}
if (i == 26) res.push_back(a);
}
return res;
}
vector<int> helper(string& word) {
vector<int> res(26);
for (char c : word) ++res[c - 'a'];
return res;
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/916
參考資料:
https://leetcode.com/problems/word-subsets/
https://leetcode.com/problems/word-subsets/discuss/175854/C%2B%2BJavaPython-Straight-Forward
[LeetCode All in One 題目講解匯總(持續更新中...)](https://www.cnblogs.com/grandyang/p/4606334.html)