递归算法的时空复杂度 一些其他解释

问题描述

n转换为其英文单词表示形式,其中0 n

Python解决方案:

class Solution:
    def helper(self,n):
        ones = ['','One','Two','Three','Four','Five','Six','Seven','Eight','Nine']
        teens = ['Ten','Eleven','Twelve','Thirteen','Fourteen','Fifteen','Sixteen','Seventeen','Eighteen','Nineteen']
        tens = ['','','Twenty','Thirty','Forty','Fifty','Sixty','Seventy','Eighty','Ninety']

        res = ''
        if n < 10:
            res = ones[n]
        elif n < 20:
            res = teens[n - 10]
        elif n < 100:
            res = tens[n // 10] + ' ' + self.helper(n % 10)
        elif n < 1000:
            res = self.helper(n // 100) + ' Hundred ' + self.helper(n % 100)
        elif n < 1000000:
            res = self.helper(n // 1000) + ' Thousand ' + self.helper(n % 1000)
        elif n < 1000000000:
            res = self.helper(n // 1000000) + ' Million ' + self.helper(n % 1000000)
        return res.strip()


    def convert_to_word(self,n):
        if n == 0:
            return 'Zero'
        return self.helper(n)

我一直在尝试计算此解决方案的时间和空间复杂度。我看到了不同的答案。有人说时间复杂度为O(1),因为辅助函数调用了固定的次数(即使n是一个大数)。其他人说它是O(log(n))。

空间复杂度似乎是O(1)?

我很困惑。请帮我澄清一下。谢谢。

解决方法

在所有大于1000000000的输入n上,该函数立即返回一个空字符串,而无需进行任何计算或递归调用。因此,时间复杂度当然是O(1),空间复杂度也是如此(因为较小的n所发生的事情完全不相关)。

如果您删除该行,情况将有所不同,并且会更有趣

elif n < 1000000000

,因此对于大的n,您将得到一个(虚拟的)无限制的结果字符串,其中包含无限制的Million个子字符串(忽略整数在实际计算机上的最大大小这一事实,并且忽略了这样的事实:您将获得无意义的数字单词)。在这种情况下,您将获得时间复杂度O(log(n)^2)(因为您正在连接长度为O(log n)的{​​{1}}个字符串)和空间复杂度O(log n)(由于递归调用)。通过更有效地处理字符串连接,可以轻松地将时间复杂度降低到O(log n)


一些其他解释

从评论看来,为什么时间复杂度为O(1)并不明显。如果我们说时间复杂度 T(n)在O(1)中,则意味着存在一个常数 c 和一个常数 k 对于所有 n> k T(n)。

在此示例中,选择O(log n)c = 9可以解决问题,或者选择k = 0,因此时间复杂度为O(1)。现在还应该清楚,以下函数也是O(1)(尽管具有很大的隐藏常数因子):

c = 1 and k = 1000000000