时空复杂性在Python中对列表进行混排时(不使用内置函数)

时间:2018-09-08 13:48:53

标签: python time-complexity shuffle space-complexity

我现在正在学习Python,

我想实现一个接受整数列表的函数(假设它具有N个元素) 并随机打印此列表,而无需重复。

我尝试使用我在网站上阅读的想法,并实现了两个功能,

我很高兴了解每种功能, 时间和空间的复杂度是多少?

预先感谢

import random
def shuffle1(arr):
    for n in range(len(arr) - 1):
        rnd = random.randint(0, (len(arr) - 1))
        val1 = arr[rnd]
        val2 = arr[rnd - 1]

        arr[rnd - 1] = val1
        arr[rnd] = val2

    print(arr)

Arr1 = [1, 2, 3, 4, 5]
shuffle1(Arr1)

import random
def shuffle2(Arr):
    result = []
    while len(Arr) > 0:
        index = random.randrange(0,len(Arr))
        result.append(Arr.pop(index))
    print(result)


Arr1 = [1, 2, 3, 4, 5]
shuffle2(Arr1)

1 个答案:

答案 0 :(得分:0)

  

我的假设(应该是合理的)是random.randint(0, n)的时间复杂度与n中的位数成正比。

复杂度表示为输入大小的函数。
在第一种情况下,您有一个循环运行n次,其中n是列表的大小,内部有一个random.randint调用,其长度的位数是线性的列表中。因此,您有O(nlogn)。也就是说,您执行nlogn操作。

在第二种情况下,您使用pop(请参阅here),在最坏的情况下,可能是O(k)k<=n。因此,运行时间为O(n^2)。您可以将其视为(n+log(n)+(n-1)+log(n-1)+…+1+log(1))
O(n^2)最坏的情况最好的情况(您总是随机选择大小调整后的列表的最后一个元素)是O(nlogn)(请参见Stirling's approximation了解更多信息。

例如,该算法具有O(f)的时间复杂度,因为无论如何迭代次数都是10 ^ 9,其中frandom.sample()的时间复杂度。

import random

def shuffle1(lst):
    for _ in range(1000000000):
        pos1, pos2 = random.sample(range(len(lst)),2) 
        lst[pos1], lst[pos2] = lst[pos2], lst[pos1]

空间复杂度是指算法相对于输入大小所需的工作内存大小。
在第一种情况下,您使用O(1)辅助空间,即仅2个变量将值存储在要交换的2个位置(常数)。请注意,未考虑输入列表的大小。
在第二种情况下,您将构造一个新的大小为n的列表,即O(n)