algorithm - 我的算法可以做得更好吗?

标签 algorithm

我面临着为一项任务制定最有效算法的挑战。现在我来到了 n * logn 的复杂性。我想知道是否有可能做得更好。所以基本上任务是让 children 玩数数游戏。给你的数字 n 是 child 的数量,m 是你在执行之前跳过某人的次数。您需要返回一个给出执行顺序的列表。我试着这样做,你使用跳过列表。

Current = m
while table.size>0:
    executed.add(table[current%table.size])
    table.remove(current%table.size)
    Current += m

我的问题是这是否正确?它是 n*logn,你能做得更好吗?

最佳答案

Is this correct?

没有。 当您从表中删除一个元素时,table.size 会减小,并且 current % table.size 表达式通常最终会指向另一个不相关的元素。 例如,44 % 11044 % 104,这是一个完全不同位置的元素.

Is it n*logn?

没有。 如果 table 只是一个随机访问数组,它可以执行 n 操作来删除一个元素。 例如,如果 m = 1,程序在修正上述点后,总是会删除数组的第一个元素。 当数组实现足够简单时,每次都需要 table.size 操作来重新定位数组,导致总共大约 n^2/2 操作。

现在,将是 n log n 如果 table 被备份,例如,通过具有隐式索引的平衡二叉搜索树而不是键,以及拆分和合并原语。这是一个陷阱,例如,here是快速搜索英文资源的结果。 这样的数据结构可以用作访问、合并和拆分成本为 O(log n) 的数组。 但到目前为止,没有任何迹象表明是这种情况,而且大多数语言的标准库中都没有这样的数据结构。

Can you do it better?

更正:部分,是;完全,也许。

如果我们向后解决问题,我们有以下子问题。

设一圈k个 child ,指针当前在 child t。 我们知道,就在刚才,有一圈 k + 1 child ,但我们不知道指针在哪里,在哪个 child x 上。 然后我们数到 m,去掉 kid,指针结束在 t我们刚刚删除了谁x 是什么?

原来“x 是什么”部分可以在 O(1) 中解决(绘图在这里很有帮助),所以找到最后一个站着的 child 是在 O(n) 中可行。 正如评论中指出的那样,整个过程称为 Josephus Problem ,及其变体得到了广泛研究,例如,在 Knuth 等人的《具体数学》中。

但是,在每步 O(1) 中,这只会找到最后一个站着的 child 的号码。 它不会自动给出计算 child 出局的完整顺序。 当然有一些方法可以使每一步 O(log(n)),总共 O(n log(n))。 但是至于O(1),我暂时不知道。

关于algorithm - 我的算法可以做得更好吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43363796/

相关文章:

algorithm - 给定一个具有不同值的预排序数组,找到满足 A[i]=i 的 x

algorithm - 缩短句子的算法问题

algorithm - 线段与凸多边形的交集

c# - 将字符串分解并重新排列成所有可能的组合

algorithm - 给定一个循环链表,找到一个合适的头,使得值的运行总和永远不会为负

计算分区数量的算法?

algorithm - 网络流量 : Can I change edge capacity while solving for max flow?

c++ - 有没有办法以 vector 形式访问内存映射?

c++ - 我需要一个类似于堆栈但具有随机访问功能的数据结构,但是我应该实现什么?

algorithm - 100万节点的链表如何实现?