这个题是比较难的一个题,每批输入给的单词数和谜题数都很多,O(
N
2
N^2
N2)是行不通的。由于题目中要求单词中字母的多样性要少于谜题,即匹配代表着单词中的字母在谜题中都出现。所以我们预存所有单词的表示到哈希表中,同时计算谜题的所有子集(谜题长度最多7位)。这样查找谜题,就会变快。
这里有两个难点,一个是字母的表示,由于每个字母最多一次,不需要用质数,这里用bitmap即可。第二个是子集的获取,可以用递归的算法一行得出,这个也是很妙的地方。
from collections import defaultdict
class Solution:
def findNumOfValidWords(self, words: List[str], puzzles: List[str]) -> List[int]:
def subsets(nums: List[int]) -> List[List[int]]:
res = [[]]
for num in nums:
res = res + [[num] + i for i in res]
return res
def word2bitmap(word):
bitmap = 0
c0 = Counter(word)
for c in c0:
num = ord(c)-ord('a')
bitmap += (1 << num)
return bitmap
ret = [0 for _ in puzzles]
# 构建word hashmap
bitmapcount = defaultdict(int)
for word in words:
bitmap = word2bitmap(word)
bitmapcount[bitmap] += 1
for i, puzzle in enumerate(puzzles):
first_c = puzzle[0]
c0 = Counter(puzzle)
dis_puz = []
for c in c0:
if c not in first_c:
dis_puz.append(c)
puzzs = subsets(dis_puz)
for puzz in puzzs:
bitmap = word2bitmap(puzz) + word2bitmap([first_c])
ret[i] += bitmapcount[bitmap]
return ret