【发布时间】:2016-02-17 16:59:09
【问题描述】:
我知道已经提出并解决了类似的问题 (Time complexity of python code for finding the longest word that can be made of other words in the list),但我有一个后续问题。
我有以下问题,
# Given a list of words, find the longest word made of other words in the list.
# Example: [cat, banana, dog, nana, walk, walker, dogwalker]
# Result: dogwalker
我在 Python 3 中有以下实现:
def find_longest_word(list_words):
list_words = sorted(list_words, key=lambda x:len(x))[::-1]
for elem in list_words:
set_remaining = set(list_words) - set([elem])
if find_if_composite(elem, set_remaining, {}):
return elem
return None
def find_if_composite(s, set_):
n = len(s)
if len(set_) == 0 or n == 0:
return False
if s in set_:
return True
for i in range(1, n+1):
this_s = s[:i]
if this_s in set_:
if find_if_composite(s[i:], set_): # assuming that I can reuse the string
return True
return False
我们从上一个答案中知道,这段代码运行时间为 O(N!),其中 N 是字符串的大小(如果我是正确的)。
我的问题是:有什么方法可以提高时间复杂度(例如,使用记忆化)?如果不是,为什么?如果是,如何?我尝试了以下代码,但似乎它在递归调用期间从未命中备忘录。
def find_if_composite_memo(s, set_, memo):
n = len(s)
if len(set_) == 0 or n == 0:
return False
if s in memo:
return memo[s]
if s in set_:
return True
for i in range(1, n+1):
this_s = s[:i]
if this_s in set_:
if find_if_composite_memo(s[i:], set_, memo):
memo[s] = True
memo[s[i:]] = True
return True
memo[s] = False
return False
要测试,请使用
b = ["cat", "banana", "dog", "nana", "walk", "walker", "dogwalker", "dogwalkerbanana"]
print(find_longest_word(b))
【问题讨论】:
标签: python algorithm recursion time-complexity memoization