问题描述:
我们给出两个单词数组A
和 B
。每个单词都是一串小写字母。
现在,如果b
中的每个字母都出现在a
中,包括重复出现的字母,那么称单词b
是单词a
的子集。 例如,“wrr”
是 “warrior”
的子集,但不是 “world”
的子集。
如果对B
中的每一个单词b
,b
都是a
的子集,那么我们称A
中的单词a
是通用的。
你可以按任意顺序以列表形式返回A
中所有的通用单词。
示例 :
输入:A = [“amazon”,“apple”,“facebook”,“google”,“leetcode”], B = [“lo”,“eo”]
输出:[“google”,“leetcode”]
提示:
1 <= A.length, B.length <= 10000
1 <= A[i].length, B[i].length <= 10
A[i]
和B[i]
只由小写字母组成。A[i]
中所有的单词都是独一无二的,也就是说不存在i != j
使得A[i] == A[j]
。
问题分析:
先来理解题目,题目强调的是单个字母,不存在字母顺序问题,所以只要统计出B
中每个小写字母,在所有的单词中出现次数最高的那个数(例如,B = ["loo","eo"]
,那么o
最大的出现次数为2
, 因为在"loo"
出现了两次,在"eo"
出现了一次,所以以最大的为准),然后再统计A
中的每个单词中的每个字母出现的次数,与其对比即可。
具体思路:
(1)先统计出数组B
中每个小写字母的最大出现次数,因为是题目只包含26个小写字母,所以,可以直接转换成数组来保存。(这这个过程中,可以用字典或者hash
来保存,这样可能会更快一些)
(2)然后,依次统计A
中的没单词中每个字母的出现个数,与(1)统计的结果做对比,选择出通用单词即可。
Python3实现:
class Solution:
def wordSubsets(self, A, B):
def count(word): # 统计单词中每个字母出现的次数
cnt = [0] * 26
for letter in word:
cnt[ord(letter) - ord('a')] += 1
return cnt
bmax = [0] * 26
for b in B:
for i, c in enumerate(count(b)):
bmax[i] = max(bmax[i], c) # 选择出现次数最多那个作为后面比较的标准
res = []
for a in A: # 判断 A 中的每个单词,并依次添加到结果
if all(x >= y for x, y in zip(count(a), bmax)):
res.append(a)
return res
if __name__ == '__main__':
A, B = ["amazon", "apple", "facebook", "google", "leetcode"], ["e", "o"]
solu = Solution()
print(solu.wordSubsets(A, B))