解法
感觉好像单纯是翻译一下官解哈哈哈哈
解法一:成对的TRIE
对于长度相同的前后缀,比如abc
和xyz
,可以表示为('a','z')
、('b','y')
、('c','x')
但是对于长度不等的,可以用None
来表示空位
综上就是把TRIE的搜索路径表示为itertools.izip_longest(prefix,suffix[::-1])
难点在于TRIE的构造,见注释:
class WordFilter(object):
def __init__(self, words):
"""
:type words: List[str]
"""
from collections import defaultdict
Trie = lambda:defaultdict(Trie)
self.trie = Trie()
WEIGHT = 0
for weight,word in enumerate(words):
cur = self.trie
cur[WEIGHT] = weight
for i,w in enumerate(word):
# 现在已经遍历了深度i,(即prefix和suffix里短的那个长为i),要往i+1迈进
# 那些`suffix`还维持在长度i,但是`prefix`更长的情况
tmp = cur
for c in word[i:]:
tmp = tmp[c,None]
tmp[WEIGHT] = weight
# 那些`prefix`还维持在长度i,但是`suffix`更长的情况
tmp = cur
for c in word[:-i or None][::-1]:
tmp = tmp[None,c]
tmp[WEIGHT] = weight
# 更新长度相等的时候的值
cur = cur[w,word[-i-1]]
cur[WEIGHT] = weight
def f(self, prefix, suffix):
"""
:type prefix: str
:type suffix: str
:rtype: int
"""
root = reduce(dict.__getitem__, itertools.izip_longest(prefix,suffix[::-1]), self.trie)
if 0 in root:
return root[0]
return -1
解法二:拼接后缀
对于单词apple
,的可能后缀e
、ple
等,可以组成新的字符串e#apple
、ple#apple
把这两个字符串加到TRIE里,那么搜索的时候就是直接搜suffix#prefix
在不在TRIE里就行了
比如prefix = app, suffix = ple
时,搜ple#app
就行搜到了
class WordFilter(object):
def __init__(self, words):
"""
:type words: List[str]
"""
from collections import defaultdict
import functools
Trie = lambda:defaultdict(Trie)
self.trie = Trie()
WEIGHT = 0
def deal(x,y,weight):
x[WEIGHT] = weight
return x[y]
for weight,word in enumerate(words):
cur = self.trie
cur[WEIGHT] = weight
for i in range(len(word)+1):
root = reduce(functools.partial(deal,weight=weight),word[i:]+'#'+word,self.trie)
root[WEIGHT] = weight
def f(self, prefix, suffix):
"""
:type prefix: str
:type suffix: str
:rtype: int
"""
root = reduce(dict.__getitem__, suffix+"#"+prefix, self.trie)
if 0 in root:
return root[0]
return -1