Skip to content

Commit 2ffd350

Browse files
authored
Create number-of-valid-words-for-each-puzzle.py
1 parent 322ba88 commit 2ffd350

File tree

1 file changed

+75
-0
lines changed

1 file changed

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

0 commit comments

Comments
 (0)