916. Word Subsets**

​https://leetcode.com/problems/word-subsets/​

题目描述

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]​​​ and​​B[i]​​ consist only of lowercase letters.
  • All words in​​A[i]​​​ are unique: there isn’t​​i != j​​​ with​​A[i] == A[j]​​.

C++ 实现 1

从题目中的限制条件可以看出, ​​A​​​ 和 ​​B​​​ 的长度最大 10000, 显然不能直接两个 for 循环, 必须要优化. 看到题目中对于 ​​universal​​​ 的定义, 那么只需要求出 ​​B​​​ 中各个字符(注意是是各个字符而不是各个字符串)的最大值, 再一次判断 ​​A​​​ 中的每个字符串是否对 ​​B​​ 是 Universal 的.

思路参考 LeetCode 的官方 Solution: ​​https://leetcode.com/problems/word-subsets/solution/​

class Solution {
private:
vector<int> count(const string &s) {
vector<int> ans(26, 0);
for (auto &c : s) ans[c - 'a'] ++;
return ans;
}
bool isUniversal(const vector<int> &record, const vector<int> &ans) {
for (int i = 0; i < 26; ++ i)
if (ans[i] < record[i]) return false;
return true;
}
public:
vector<string> wordSubsets(vector<string>& A, vector<string>& B) {
vector<int> record(26, 0);
// count(s) 统计 B 中每个字符串 s 的各个字符个数,
// record 保存各个字符个数的最大值, 具体原因看题目中 universal 的定义
for (auto &s : B) {
auto ans = count(s);
for (int i = 0; i < 26; ++ i)
record[i] = max(record[i], ans[i]);
}
vector<string> res;
for (auto &a : A) {
auto ans = count(a);
bool is_universal = isUniversal(record, ans);
if (is_universal) res.push_back(a);
}
return res;
}
};