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

时间:2017-04-12 08:07:27

标签: algorithm

我遇到了一个挑战,即为一项任务制作最有效的算法。现在我来到了n * logn的复杂性。我想知道是否有可能做得更好。所以基本上任务是有孩子们有一个计数游戏。您将获得数字n,即孩子的数量,以及您在执行之前跳过某人的次数。您需要返回一个给出执行顺序的列表。我尝试这样做你使用跳过列表。

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

我的问题是这样的吗?是n * logn,你能做得更好吗?

2 个答案:

答案 0 :(得分:3)

  

这是对的吗?

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

  

是n * logn吗?

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

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

  

你能做得更好吗?

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

如果我们向后解决问题,我们会遇到以下子问题。

让一群k个孩子,并且指针当前处于小孩t。 我们知道,就在刚才,有一群k + 1小孩,但我们不知道指针在哪个小孩x。 然后我们计算到m,删除了孩子,指针最终在t我们刚刚删除了哪些,什么是x

结果是"什么是x"部分可以在O(1)中解决(绘图在这里很有帮助),因此找到最后一个孩子可以在O(n)中找到。 正如评论中所指出的那样,整个事情被称为Josephus Problem,其变体被广泛研究,例如Knuth等人的具体数学。

但是,每步O(1),这只会找到最后一个站着孩子的号码。 它不会自动给出计算孩子的整个顺序。 肯定有办法让每一步O(log(n))O(n log(n))总计。 但至于O(1),我现在还不知道。

答案 1 :(得分:1)

算法的复杂性取决于操作的复杂性 table.remove(..)executed.add(..)

如果它们都具有 O(1)的复杂性,则您的算法具有 O(n)的复杂性,因为循环在 n 步骤。

虽然可以在 O(1)中轻松实现table.remove(..),但[# Children's IQ scores are normally distributed with a # mean of 100 and a standard deviation of 15. What # proportion of children are expected to have an IQ between # 80 and 120? mean=100; sd=15 lb=80; ub=120 x <- seq(-4,4,length=100)*sd + mean hx <- dnorm(x,mean,sd) plot(x, hx, type="n", xlab="IQ Values", ylab="", main="Normal Distribution", axes=FALSE) i <- x >= lb & x <= ub lines(x, hx) polygon(c(lb,x\[i\],ub), c(0,hx\[i\],0), col="red") area <- pnorm(ub, mean, sd) - pnorm(lb, mean, sd) result <- paste("P(",lb,"< IQ <",ub,") =", signif(area, digits=3)) mtext(result,3) axis(1, at=seq(40, 160, 20), pos=0)] 需要更多思考。

您可以在O(n):

中创建

将您的人员存储在 LinkedList 中,并将最后一个元素与第一个元素连接起来。删除元素需要花费 O(1)。 选择下一个选择的人将花费 O(m),但这是一个常数= O(1)

这种算法的复杂度为 O(n * m) = O(n)(对于常数m)。