forked from kamyu104/LeetCode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
number-of-valid-words-for-each-puzzle.py
75 lines (69 loc) · 2.51 KB
/
number-of-valid-words-for-each-puzzle.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# Time: O(n*l + m*L), m is the number of puzzles, L is the length of puzzles
# , n is the number of words, l is the max length of words
# Space: O(L!)
class Solution(object):
def findNumOfValidWords(self, words, puzzles):
"""
:type words: List[str]
:type puzzles: List[str]
:rtype: List[int]
"""
L = 7
def search(node, puzzle, start, first, met_first):
result = 0
if "_end" in node and met_first:
result += node["_end"];
for i in xrange(start, len(puzzle)):
if puzzle[i] not in node:
continue
result += search(node[puzzle[i]], puzzle, i+1,
first, met_first or (puzzle[i] == first))
return result
_trie = lambda: collections.defaultdict(_trie)
trie = _trie()
for word in words:
count = set(word)
if len(count) > L:
continue
word = sorted(count)
end = reduce(dict.__getitem__, word, trie)
end["_end"] = end["_end"]+1 if "_end" in end else 1
result = []
for puzzle in puzzles:
first = puzzle[0]
result.append(search(trie, sorted(puzzle), 0, first, False))
return result
# Time: O(m*2^(L-1) + n*(l+m)), m is the number of puzzles, L is the length of puzzles
# , n is the number of words, l is the max length of words
# Space: O(m*2^(L-1))
import collections
class Solution2(object):
def findNumOfValidWords(self, words, puzzles):
"""
:type words: List[str]
:type puzzles: List[str]
:rtype: List[int]
"""
L = 7
lookup = collections.defaultdict(list)
for i in xrange(len(puzzles)):
bits = []
base = 1 << (ord(puzzles[i][0])-ord('a'))
for j in xrange(1, L):
bits.append(ord(puzzles[i][j])-ord('a'))
for k in xrange(2**len(bits)):
bitset = base
for j in xrange(len(bits)):
if k & (1<<j):
bitset |= 1<<bits[j]
lookup[bitset].append(i)
result = [0]*len(puzzles)
for word in words:
bitset = 0
for c in word:
bitset |= 1<<(ord(c)-ord('a'))
if bitset not in lookup:
continue
for i in lookup[bitset]:
result[i] += 1
return result