如果您愿意假设您的随机数生成器总是会在循环回到给定抽奖的先前看到的值之前找到一个唯一值,那么这个算法是 O(m^2),其中 m 是唯一的数量您正在绘制的值。
因此,如果您从一组 n 值中提取 m 值,则第一个值将要求您最多绘制 1 以获得唯一值。第二个最多需要 2 个(您会看到第一个值,然后是唯一值),第三个 3,... 第 m 个 m。因此,您总共需要 1 + 2 + 3 + ... + m = [m*(m+1)]/2 = (m^2 + m)/2 次抽奖。这是 O(m^2)。
如果没有这个假设,我不确定你如何保证算法会完成。很有可能(尤其是使用可能有循环的伪随机数生成器),您将一遍又一遍地看到相同的值,而永远不会得到另一个唯一值。
==编辑==
对于一般情况:
在您的第一次抽奖中,您将进行 1 次抽奖。在您的第二次抽奖中,您预计会中奖 1(成功抽奖)+ 1/n(“部分”抽奖,代表您重复抽奖的机会) 在第三次抽奖中,您希望抽中 1(成功抽奖)+ 2/n(“部分”抽奖...)...在您的第 m 次抽奖中,您希望进行 1 + (m-1)/n 次抽奖。
因此,在平均情况下,您将进行 1 + (1 + 1/n) + (1 + 2/n) + ... + (1 + (m-1)/n) 次抽签。
这等于从 i=0 到 [1 + i/n] 的 (m-1) 的总和。让我们表示 sum(1 + i/n, i, 0, m-1)。
然后:
sum(1 + i/n, i, 0, m-1) = sum(1, i, 0, m-1) + sum(i/n, i, 0, m-1)
= m + sum(i/n, i, 0, m-1)
= m + (1/n) * sum(i, i, 0, m-1)
= m + (1/n)*[(m-1)*m]/2
= (m^2)/(2n) - (m)/(2n) + m
我们去掉低阶项和常数,我们得到这是 O(m^2/n),其中 m 是要绘制的数字,n 是列表的大小。