问题
def is_palindrome(s):
if len(s) <= 1:
return True
return s[0] == s[-1] and is_palindrome(s[1:-1])
My first thought was that the complexity is O(n) because each recursive call removes 2 characters.
But then I thought of the slice's complexity. According to https://wiki.python.org/moin/TimeComplexity, the complexity of getting a slice is O(k), where k = number of elements in the slice. In is_palindrome
, k = n - 2, then k = n - 4, then n - 6, etc. so I thought the complexity would be O(n^2) because each call has an (at worst) O(n) slice and there are n calls.
Which one is correct?
回答1:
Imagine you have the classic O(n^2)
algorithm: the double nested for-loop
for i in range(n):
for j in range(n):
#do_something
For every iteration of the outer loop, an entire iteration of the inner loop O(n)
must be executed. This results in an O(n^2)
runtime.
Now let's take a look at your algorithm - for every level of recursion, another O(n)
algorithm (your slice) must be called - your recursive function is analogous to the outer loop, and your slice function is analogous to the inner loop.
Your recursion function is
O(n/2) => O(n)
and your slice function is
O(t) where t < n
An alternate O(n)
way to decide whether a string is palindrome is to simply iterate over the string once and in each iteration check opposite ends of the list. Remember the index accesses are O(1)
for i in xrange(len(s)/2):
if s[i] != s[(len(s)-1)-i]:
return False
return True
来源:https://stackoverflow.com/questions/24153433/complexity-of-palindrome-test