洗了一堆钥匙

时间:2012-06-02 19:00:30

标签: algorithm shuffle

这个问题主要涉及一个改组一卡片的着名面试问题。我在SO中漫步,发现了类似的问题,但答案大多没有达到标准,或者被忽略了。

提出的问题是建立一个洗牌的功能。

我的解决方案:如果我按照任何顺序将所有卡片放在链接列表中(例如排序或未排序 - 顺序无关紧要),这是可能的。我生成一个随机数,将其mod加到当前卡的总数,并从链表中删除该索引,以将卡存储在我的shuffledArray中。

我觉得这个解决方案很棒,它有以下运行时间: O(n)用于以任何顺序构建链表。 O(n)用于从链表中删除它。 O(1)每次都产生一个随机数。

因此,该算法或多或少地具有O(n)的下限。

我担心的是空间。目前采取的空间如下: 1)链表的O(n) 2)对于shuffledArray的O(n)。

再次是O(n)的下界。

可以这样做吗?我的意思是不使用这个额外的空间。 可以在小于O(n)的时间内完成吗?

3 个答案:

答案 0 :(得分:3)

Fisher-Yates shuffle可以正常工作并完成n-1个随机数生成器。

答案 1 :(得分:0)

void shuffle(vector<T> v)
{
    int n = v.size();
    for (int i = 0; i < n; i++)
        swap(v[i], v[i+rand(n-i)]);
};

归纳证明:

  1. 单个元素向量按顺序排序
  2. 随机选择第一个元素,并通过归纳法对矢量的其余部分进行混洗

答案 2 :(得分:-1)

如何迭代卡片。在每一步中,您生成1到52之间的随机数,并使用此随机数将当前卡与卡交换?

你怎么看?