I am given a input string s ("bedbathandbeyond") and a set of words {"bed", "bath", "beyond", "bat", "hand", "and"}. I need to divide the input string s into a series of words in the dictionary. In this case, the two allowed outputs would be ["bed", "bath", "and", "beyond"] and ["bed", "bat", "hand", "beyond"]. Both outputs are allowed and none is better than the other. My solution is as follows:
def find_breakdown_rec(s, dictionary, memo = {}):
if len(s) == 0:
return True, []
if (s in memo):
return memo[s]
for i in range(len(s) + 1):
word = s[:i]
if word in dictionary:
status, words = find_breakdown_rec(s[i:], dictionary, memo)
if status:
memo[s] = [word] + words
return True, memo[s]
return False, []
If no memoization is used, the runtime is clearly exponential: we have O(n) branching factor, and O(n) as the depth: O(n ** n). With memoization, however, the algorithm seems to me polynomial: the 'find_breakdown_rec' can be called with n different inputs, and it then performs a polynomial amount of work on it. I've been told by a very knowledgeable person that it's still exponential. Could someone explain why? I've been thinking very hard about it and I'm not sure why that's the case.