回文递归算法的时间复杂性

时间:2017-10-08 08:34:52

标签: algorithm recursion time-complexity

我已经编写了这个递归函数来找到回文。

def palindrome(string):
    print("palindrome called with:"+string)
    if(len(string)<=3):
        return string[0]==string[-1]
    else:
        res=palindrome(string[1:-1])
        print("palindrome returned:"+str(res))
        return res

我现在已经找到了这个算法的时间复杂度。 我的问题 是我的基本情况吗?是len&lt; = 3? 我无法将此与斐波纳契和因子算法的经典示例联系起来,这些算法遍布互联网。

1 个答案:

答案 0 :(得分:4)

是的,事实是只有你的基本情况是正确的。

所以你应该在这里做的是,检查第一个和最后一个字符是否相同,然后检查剩下的字符串是否也是回文。 但是在任何时候你都没有检查过。

因此,如果代码中的更改很少,则以下解决方案将起作用,如果将空字符串作为参数传递,则会失败。

def palindrome(string):
    print("palindrome called with:"+string)
    if(len(string)<=3):
        return string[0]==string[-1]
    else:
        if string[0] == string[-1]:
            res=palindrome(string[1:-1])
            print("palindrome returned:"+str(res))
            return res
        else:
            return False

当然,有更好的方式来写这个。

def palindrome(s):
    return s == '' or (s[0]==s[-1] and palindrome(s[1:-1]))

我所做的就是通过让它再进行两次递归调用来进一步减少你的基本情况。

现在,进入时间复杂度,这两个代码都相同。

在一个函数调用中,我们正在进行O(1)比较第一个和最后一个字符的操作。此递归调用最多只进行n/2次。 n/2因为,在长度为n的字符串中,我们会在每次调用中删除2个字符。因此,总体复杂度将为O(n)。(请记住,这会忽略每次递归调用中的字符串复制/切片。)

最后,你应该以递归方式避免这种情况,因为我们在每次递归调用之前都会创建一个新字符串(在切片时)。

def palindrome(s):
    def _palindrome(string, i, j):
        if i >= j:
            return True
        return string[i] == string[j] and _palindrome(string, i + 1, j - 1)
    return _palindrome(s, 0, len(s) - 1)

这不会在每次通话时复制。因此,绝对是O(n)解决方案。