【问题标题】:Algorithm that sorts n numbers from 0 to n^m in O(n)? where m is a constant在O(n)中将n个数字从0排序到n ^ m的算法?其中 m 是一个常数
【发布时间】:2018-04-06 10:13:33
【问题描述】:

所以我遇到了这个问题:

我们必须在 0 和 n^3 之间对 n 个数字进行排序,时间复杂度的答案是 O(n),作者是这样解决的:

首先我们将这些数字的基数转换为 O(n) 中的 n,因此现在我们有最多 3 位数字(因为 n^3)

现在我们使用基数排序,因此时间是 O(n)

所以我有三个问题:

1.这是正确的吗?最好的时间?

2.如何在 O(n) 中转换 n 个数字的基数?像每个数字的 O(1) 一样?因为本网站以前的一些主题说它的 O(M(n) log(n))?!

3. 如果这是真的,那么这意味着我们可以在 O(n) 中对从 0 到 n^m 的任意 n 个数字进行排序?!

( 我搜索了关于转换 n 个数字的基数,有人说它 每个数字的 O(logn),有些人说 n 个数字的 O(n),所以我也对此感到困惑)

【问题讨论】:

  • 我声明说 k=3 是 this 算法的常数是作弊,但要求竞争算法在其 O() 公式中使用 log(n)

标签: algorithm sorting


【解决方案1】:

1) 是的,没错。这是可能的最佳复杂性,因为任何排序都必须至少查看数字,即 O(n)

2) 是的,每个数字都在 O(1) 中转换为 base-n。执行此操作的简单方法在位数上采用 O(m^2),通常假设您可以对高达 O(n) 的数字进行算术运算O(1) 时间。 m 是常数,所以 O(m^2)O(1)... 但实际上这一步只是说基数您在基数排序中使用的是 O(n)。如果你真的实现了这个,你会使用 2 >= n 的最小幂,所以你不需要这些转换。

3) 是,如果 m常数。最简单的方法是在 LSB 优先的基数排序中采用 m 次,基数约为 n。每次通过需要 O(n) 时间,并且该算法需要 O(n) 额外的内存(以可以容纳 n 的单词来衡量)。

所以作者是对的。然而,在实践中,这通常是从另一个方向接近的。如果您要编写一个对机器整数进行排序的函数,那么在一些较大的输入大小下,如果您切换到基数排序,它会更快。如果 W 是最大整数大小,那么这个权衡点将是当 n >= 2^(W/m) 对于某个常数 m . 这和你的约束说的一样,但清楚地表明我们只考虑大尺寸的输入

【讨论】:

  • 感谢您的回答,所以每当我们拥有一台现代计算机时,我可以假设我可以更改 O(1) 中数字的基数吗? (因为在考试中他们通常只是问我们解决问题的最佳时间复杂度是多少,而他们并没有提供关于计算机等的太多细节)
  • 关于改变数字基数的复杂性的问题通常不是关于恒定大小的数字,所以不,答案通常不是 O(1)。正如我所指出的,即使在这里,关于改变基础的一点也是不必要的。作者之所以这样做,是因为这是解释基数排序如何采用恒定次数的最简单方法。
  • 但我认为基数排序的时间复杂度是 O(nk) 其中 k 是我们可以拥有的最大位数?我的意思是我们不应该有一个循环并在算法中重复它 k 次,因此需要进行这种转换吗?抱歉,我没有得到你所说的使用 2 >= n 的最小幂的部分
  • k=m,此时m为常数,所以O(nk) = O(n)
【解决方案2】:

基数排序是O(n)的假设是错误的,它不是。

如 wiki 上所述:

如果所有 n 个键都是不同的,那么 w 必须至少为 log n 随机存取机器能够将它们存储在内存中,这给出了 充其量是 O(n log n) 的时间复杂度。

答案是否定的,“作者实现”(充其量)是n log n。同样转换这些数字可能需要超过 O(n)

【讨论】:

  • 基数时间复杂度为 O(k(n+m)) 其中 k 是最大位数,m 是底数,在这个问题中,当我们转换底数时,最大位数我们的数字变为 3,因为它们介于 0 和 n^3 之间,因此基数排序将是 O(n)。我知道这部分是事实,但我不明白如何在 O(n) 中转换 n 个数字的基数
  • @OneAndOnly 如果您需要转换 n 数字的基数,根据定义,它会是 O(n),因为对于每个数字,您都有一个 O(1) 操作,重复 @987654325 @时代。这里的问题是作者没有n 数字,但n^3 我真的不知道切换基数会如何改善任何事情。
  • @ChatterOne 不,我们实际上有 n 个数字,介于 0 和 n^3 之间(我的错,我认为这个问题有点含糊,我已解决),以及如何将数字转换为O(1)中的任何基础?我尝试了谷歌搜索以及他们谈论的每个 stackoverflow 主题 logn 等等,这让我感到困惑?
  • @ChatterOne 例如这个话题,他们说复杂度是 O(M(n) log(n)) ! stackoverflow.com/questions/28418332/…
  • @OneAndOnly re:转换基数:从这个意义上说,每个基本算术运算都是 log(n),其中 n = 位数。 libik 谈论转换固定最大大小的数字。
【解决方案3】:
  1. 这是正确的吗?

是的,它是正确的。如果以 n 为基数,则需要 3 次基数排序,其中 3 为常数,由于时间复杂度忽略常数因素,因此为 O(n)。

最好的时间是什么?

并非总是如此。根据 n 的最大值,可以使用更大的基数,以便在 2 次基数排序或 1 次计数排序中完成排序。

  1. 如何在 O(n) 中转换 n 个数字的基数?每个数字都像 O(1)?

O(1) 仅表示恒定的时间复杂度 == 每个数字的固定操作数。如果只考虑时间复杂度,选择的方法是否不是最快的也没关系。例如,使用 a, b, c 表示最高到最低有效数字,x 表示数字,然后使用整数数学:a = x/(n^2), b = (x-(a*n^2)) /n, c = x%n(假设 x >= 0)。 (旁注 - 如果 n 是常数,则优化编译器可能会将除法转换为乘法和移位序列)。

  1. 如果这是真的,那么这意味着我们可以在 O(n) 中对从 0 到 n^m 的任意 n 个数字进行排序?!

仅当 m 被认为是常数时。否则为 O(m n)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-02
    • 2019-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多