我现在正在学习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)
答案 0 :(得分:0)
我的假设(应该是合理的)是
random.randint(0, n)
的时间复杂度与n
中的位数成正比。
复杂度表示为输入大小的函数。
在第一种情况下,您有一个循环运行n
次,其中n
是列表的大小,内部有一个random.randint
调用,其长度的位数是线性的列表中。因此,您有O(nlogn)
。也就是说,您执行n
次logn
操作。
在第二种情况下,您使用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,其中f
是random.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)
。