【问题标题】:How to sort a list with given range in O(n)如何在 O(n) 中对具有给定范围的列表进行排序
【发布时间】:2016-04-18 09:18:08
【问题描述】:

如果我有一个大小为 n 的列表,并且我知道列表中的数字将介于 1 和 2n 之间,我将如何解决最坏情况为 O(n) 的问题?

我在想,如果它在 1 和 n 之间,我可以只取该数字并将其与该数字的数组值交换 - 1 但如果有任何重复,它就不会排序。

我正在考虑对数字在 1 到 2n 之间的列表采用类似的方法,但我似乎无法弄清楚。有什么帮助吗?

【问题讨论】:

  • n 能有多大?只要 n 不比列表的长度大多少,计数排序是迄今为止最快的解决方案。
  • 虽然不是一个非常Java的问题......
  • @SpiderPig n 将是列表的大小,其中 n 可以是任意大小

标签: algorithm sorting


【解决方案1】:

Counting Sort 在您的情况下可以在 O(n) 中运行。看看维基百科的定义

计数排序是一种对对象集合进行排序的算法 根据小整数的键;也就是说,它是一个整数 排序算法。它通过计算对象的数量来操作 具有每个不同的键值,并在这些计数上使用算术 确定输出序列中每个键值的位置。它的 运行时间与项目数和差异呈线性关系 在最大和最小键值之间,所以它只适用于 在键的变化不是的情况下直接使用 明显大于项目数

http://en.wikipedia.org/wiki/Counting_sort

【讨论】:

    【解决方案2】:

    您通常需要一个非比较排序来在 O(n) 时间内排序,但这是在您已经获得某些信息的情况下。有三种“主要”非比较排序算法可供选择:计数排序、基数排序和桶排序。

    如果您知道输入是小整数,请使用计数排序。根据维基百科,“计数排序仅适用于键的变化不明显大于项目数的情况。” http://en.wikipedia.org/wiki/Counting_sort

    如果您要排序的所有数字都具有相同数量的整数,则可以使用基数排序。例如:211、311、122。

    桶排序似乎是您的最佳选择。你的方法听起来不错,但你不需要一个从 1 到 2n 的数组,每个数字都有一个索引。在桶排序中,您可以有一个从 1 到 20 的数组,并且在每个元素中都有一个类似于链表的东西。因此,如果您放置数字 109,它可能对应于索引 10。

    【讨论】:

      【解决方案3】:

      您可以在此处使用基数排序。当您对输入有限制时,例如在您的情况下,它运行良好。在此处查看算法 - http://en.wikipedia.org/wiki/Radix_sort

      【讨论】:

      • 对于这样一个定义明确的问题,计数优于基数。
      【解决方案4】:

      你可以使用基数排序,计数排序,有很多O(n)排序。

      但问题是让你真的很容易......

      在 Java 中:

      int [n] input = {your list of n numbers}; int [2*n] listinorder; int [n] output;
      
      for (int i=0, i<2n, i++) listinorder[i] = -1; // set all values of listinorder to -1
      
      for (int i=0, i < n, i++) listinorder[input[i]] = input[i]; // set the ith value of listinorder to i
      
      int j=0;
      
      for (int i=0, i<2n, i++) if (listinorder(i)  != -1) {output[j] = i; j++};
      

      英文:

      1. 建立一个长度为 2n 的数组(比如 listinorder)。
      2. 将每个值设置为 -1。逐步浏览输入列表。
      3. 对于输入列表中的每个值i,设置对应的值 listinorder 我(即listinorder[i]=i)。然后通过 listinorder 的值不是 -1 以生成排序列表。

      所有 O(n)。

      【讨论】:

      • "listinorder[i]=i" - 你假设任何给定的数字在输入中只出现一次。
      猜你喜欢
      • 1970-01-01
      • 2019-11-05
      • 2011-10-18
      • 2021-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-16
      • 2018-06-23
      相关资源
      最近更新 更多