I am preparing for some coding interviews and came up with a solution to the following problem:
"Find longest word that can be made of other words in a list of words".
I have a hard time figuring out the time complexity of my algorithm. It would be great, if you can help me to figure out the time complexity of the following code.
It is more than n²
(n⋅log n
for sorting, number_of_words ⋅ word_length + recursion
), but not sure how to calculate the exact complexity due to recursion part.
def valid_pair(a,b, words):
return a in words and b in words
def valid_word(word, words):
for i in range(len(word)):
left, right = word[:i], word[i:]
valid = valid_pair(left, right, words)
if valid:
return valid
elif left in words:
return valid_word(right, words)
return False
words = ["cde","abcde","bcd","c","d","e","a"]
words = sorted(words, key = len, reverse = True)
for w in words:
if valid_word(w, words):
print w
break
Let
n
be the number of words in the list andm
the length of the longest word.The for-loop iterates over the
words
untilvalid_word
returnstrue
. The worst case would be, that non of the words can be concatenated from other words in the list. So this gives you a factorn
.valid_word
iterates over all characters in a word and callsvalid_pair
which has the complexityO(f)
, wheref = f(n,m)
is the complexity of thein
operator. (I don't know, how it is implemented). If for every characterleft
is inwords
, butright
is not,valid_word
is called recursivelym
times, resulting in this formula:So
valid_word
is inO(m!⋅f(n,m))
(this can be improved).The over all complexity is
O(n⋅m!⋅f(n,m) + n⋅log(n))
. This is an upper bound, so maybe you can improve this, by showing that it is not possible to have an input that forces the algorithm to do all the steps.But think of an input like this (withe spaces are only for better readability)
Non of these words can be concatenated from the others, but the algorithm has to try many combinations. This examples can be improved and extended.