提高时间复杂度"增加数字表示的数字"

时间:2015-07-02 15:54:19

标签: python algorithm time-complexity

问题 给定一个非负数表示为数字数组,

将数字加1(增加数字所代表的数字)。

存储数字,使最高位数位于列表的开头。

示例:

如果载体有[1,2,3]

返回的矢量应为[1,2,4]

为123 + 1 = 124。

我的代码

def plusOne(A):
    num = 0

    for digit in A:
        num = num*10 + digit

    retnum = num + 1

    retA = []

    while retnum > 0:
        retA.append(retnum % 10)
        retnum /= 10

    return retA[::-1]

好吧,我得到了正确答案。 但是,我对代码的时间复杂性并不满意。 建议改进此代码。

3 个答案:

答案 0 :(得分:6)

你的方法的复杂性是O(n),在最坏的情况下,你无法在大复杂性方面做得更好。

改变大复杂性并不是唯一重要的事情。 Big-o表示法没有考虑乘法和加法常量,这并不意味着这样的常量不会影响算法的性能。例如,在您的代码中,您执行了2 O(n)个循环。在第一个循环中,您执行一些算术运算,而在第二个循环中,您使用append,它已经分摊了最坏情况O(1),但是(引用文档):

  

[...]依赖"摊销" "摊销最坏情况"的一部分。根据容器的历史,个别行动可能需要很长时间。

您可以使用(我认为)较小的常量执行相同的操作。例如:

i = len(A) - 1

while i >= 0 and A[i]==9:
  A[i]=0
  i=i-1

if i >= 0:
  A[i] = A[i]+1
else:
  A.insert(0,1)

第一个循环在最坏的情况下需要O(n)时间(全部为9)。然而,在平均情况下,循环小于O(n)。当我们在最坏的情况下退出循环时,我们需要在列表的开头插入一个元素,该元素具有非摊销的 O(n)复杂度。

在一般情况下,这种方法应该更快,但它不会改变最坏情况的O(n)复杂性

答案 1 :(得分:2)

您无法提高O(n)时间复杂度,因为如果输入全部是9,那么您必须将n nines更改为零并在开头添加一个:

def increment(digits):
    for i in reversed(range(len(digits))):
        if digits[i] != 9:
           digits[i] += 1
           break
        else:
           digits[i] = 0
    else: # no break, all 9s
        digits.insert(0, 1) # 

示例:

>>> a = [1, 2, 3]
>>> increment(a)
>>> a
[1, 2, 4]

阵列增长在"所有9s"情况下:

>>> a = [9, 9, 9]
>>> increment(a)
>>> a
[1, 0, 0, 0]

答案 2 :(得分:1)

您的代码已经具有O(n)时间复杂度。 所以我认为没有比这更好的时间复杂性了 但是,正如上面的答案中所指出的,有一些方法可以提高代码的整体效率。