这个问题主要涉及一个改组一卡片的着名面试问题。我在SO中漫步,发现了类似的问题,但答案大多没有达到标准,或者被忽略了。
提出的问题是建立一个洗牌的功能。
我的解决方案:如果我按照任何顺序将所有卡片放在链接列表中(例如排序或未排序 - 顺序无关紧要),这是可能的。我生成一个随机数,将其mod加到当前卡的总数,并从链表中删除该索引,以将卡存储在我的shuffledArray中。
我觉得这个解决方案很棒,它有以下运行时间: O(n)用于以任何顺序构建链表。 O(n)用于从链表中删除它。 O(1)每次都产生一个随机数。
因此,该算法或多或少地具有O(n)的下限。
我担心的是空间。目前采取的空间如下: 1)链表的O(n) 2)对于shuffledArray的O(n)。
再次是O(n)的下界。
可以这样做吗?我的意思是不使用这个额外的空间。 可以在小于O(n)的时间内完成吗?
答案 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)]);
};
归纳证明:
答案 2 :(得分:-1)
如何迭代卡片。在每一步中,您生成1到52之间的随机数,并使用此随机数将当前卡与卡交换?
你怎么看?