【问题标题】:Most efficient algorithm for this problem这个问题最有效的算法
【发布时间】:2020-09-30 07:56:54
【问题描述】:

问题:假设我有一个大小为 N 的数组,范围为 [1, N]。 我想生成一个随机数 k 使得 1

这里的问题是,每次我选择一个新数字时,我都很难猜出一个尚未被占用的随机数。

我正在尝试为这个问题找到解决方案,显然是以最有效的方式(空间和复杂性)。

我想出了几个解决方案,但我认为它们的效率不是很高,而且我很难计算它们的复杂性。

Plan A) 对于我在 [1, N] 范围内随机选择的每个整数,我检查它是否被占用。如果是,我重新滚动,直到我得到一个未被占用的。这在 N 的高阶时变得低效,因为冲突非常高。

Plan B)对于每次迭代,我都会检查数组的所有值,那些我不占用的值我会写在一个列表中。之后我对列表进行洗牌(例如通过 Fisher-Yates 洗牌?)并任意获得第一个对象。这不节省空间,对于我的问题,我不能只保留一个列表并从那里随机播放,因为在我的程序中可能有多个线程计算这个。

Plan C) Plan A 的小改动:我在[1, N]范围内随机选择,我检查它是否被占用。如果是,我 +1 并尝试下一个,如果是,再次 +1。最坏的情况是所有数组槽都被占用,除了一个 -> O(N)。

有没有更好的方法来解决这个问题?这个特定问题是我软件中一个非常重要的模块,因此时间复杂度至关重要。如果没有,您认为我应该采用哪种方式(对于那些有计算时间复杂度的人才)。谢谢!

【问题讨论】:

  • @JeroenMostert 嘿,好点子!我将不得不重新提出我的问题以使这一点更加清楚。在实际问题中,可能存在不需要这些字母之一,因此新的插槽未被占用的情况。我将把它应用到帖子中
  • 一个经典的方法:定义一个数组a[i]=i。生成介于 1 和 N 之间的 k。选择 a[k]。设置 a[k]=a[N]。生成一个介于 1 和 N-1 之间的数字。选择一个[k]。设置 a[k]=a[N-1] 等
  • 为什么不做一个地址列表。仅将其随机播放一次,然后将所有线程从该列表中排在首位?您已经有了“char”数组。这只会使您的内存需求增加一倍。内存通常很便宜。 “编辑*:意识到这是你的第二个选择”
  • @xvan 阅读我写给 JeroenMostert 的内容,他也写了同样的东西
  • @Damien 修复我的回复*** 感谢您的回复,但它在某种程度上消除了在数组中随机放置字母的想法。我滚动一个随机整数,然后将其移到后面,就像说选择 k=N。所以这不起作用...感谢您的尝试!

标签: algorithm time-complexity computer-science


【解决方案1】:

我建议您同时使用计划 A 和 B。

使用 A 直到数组大部分被填满。然后搜索未使用的索引,将它们放入一个数组中,然后使用 B 计划。您将不得不试验您的约束以确定何时切换。

您对多个线程执行此操作的评论令人担忧。请注意,当多个线程访问同一内存时,很容易出现竞争条件,并且争用访问会减慢您的速度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-10
    • 2020-06-06
    • 2011-03-16
    • 2021-12-09
    • 2021-09-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多