Algorithm 计算数组中所有元素顺序的快速算法?

Algorithm 计算数组中所有元素顺序的快速算法?,algorithm,Algorithm,假设给你一个数组,数组由n个不同的元素组成,这些元素来自于一个完全有序的集合。例如,您可能会得到 137 13 7 42 38 目标是为这个元素数组生成一个匹配数组B,使得B[i]是原始数组中小于a[i]的元素数。例如,在上面的数组中,我们希望生成 A = 137 13 7 42 38 B = 4 1 0 3 2 因为137比其他四种元素(13、7、42、38)大,所以13只比其中一种元素(7)大,7比其他元素都大,以此类推 在最一般的情况下,如果数组中的元素是

假设给你一个数组,数组由n个不同的元素组成,这些元素来自于一个完全有序的集合。例如,您可能会得到

137 13 7 42 38
目标是为这个元素数组生成一个匹配数组B,使得B[i]是原始数组中小于a[i]的元素数。例如,在上面的数组中,我们希望生成

A = 137  13   7  42  38
B =   4   1   0   3   2
因为137比其他四种元素(13、7、42、38)大,所以13只比其中一种元素(7)大,7比其他元素都大,以此类推

在最一般的情况下,如果数组中的元素是只能比较的任意对象,那么在最坏的情况下,该问题的任何解决方案都必须以Ω(n lg n)运行,因为一旦我们有了这个表,我们就可以通过创建一个由n个元素组成的新数组,在O(n)时间内对数组进行排序,然后将每个元素放置在表中指定的位置。然而,我不知道的是,当元素不是任意值时,我们构造这个表的速度有多快

我的问题是:假设您得到一个由n个不同的整数值组成的数组,并希望为该数组构造一个顺序统计表。这样做最有效的算法是什么?如果有帮助的话,可以假设整数为正,并且其中最大的值为U


目前,我拥有的最好的解决方案是O(n lg n)解决方案,它的工作原理是制作数组的副本,对其进行排序,然后对原始数组中的每个整数进行二进制搜索,以找到其在新数组中的位置。这是一个很好的解决方案,但我真的希望有更好的方法来实现这一点。

最有可能的情况是,将第一个数组中的所有元素组合为n^2-n,然后将每个元素与另一个元素进行比较,以找到第一个数字,并使用第二个数组对第一个数组中的每个数字重复此操作进行计数。

至少没有基于比较的方法解决这个问题的方法比O(n logn)更好,O(n logn)是一个通用的方法。(否则,您可以应用新的神奇过程,然后在B上迭代以构建a的排序版本)


但是,如果输入数组A的整数被限制在某个已知范围内,比如[1..M],那么您可以通过标记出现在,记住它们在A中的位置,然后从索引1..M扫过L来构造B。

步骤1:对原始数组索引进行排序

A  = 137  13   7  42  38
I  =   0   1   2   3   4

A' =   7  13  38  42 137
I' =   2   1   4   3   0
步骤2:对于每个
I'[I]=j
分配
B[j]=I

I' =   2   1   4   3   0
i  =   0   1   2   3   4

B  =   4   1   0   3   2

这并没有改善big-O,但您的算法会执行两种不同的N-LogN操作。不要对数组本身进行排序,而是对
{value,originalIndex}
结构的数组进行排序

然后遍历排序的数组,执行
rank[sorted[i].originalIndex]=i

这只是一个N-LogN操作


如果U上有一个最大界,你可以用基数排序来得到O(kN)(假设你有内存)

一种方法是使用一个不完整的答案,但你可以用哪个是O(kN)来表示整数。@eulerfx-IIRC基数排序在O(n lg U)中运行,其中U是你要排序的最大整数。我相信如果你使用van-Emde-Boas树,你实际上可以把它降到O(n lg U),虽然常数因子可能要高得多。这是真的,但这是一个指数时间算法(因为M在输入中以对数M位表示)。我希望输入的大小是多项式的,当然,只有当M=o(n logn)时才有用。否则排序就可以了。这是可行的,但它是O(n^2),我已经有了一个通用的方法,即使输入不是整数,也可以在O(n lg n)中工作。请停止乞求向上投票。如果你的答案值得投票,你会得到的。问他们只是噪音,看起来很糟糕。@肯:你能解释一下为什么看起来很糟糕吗?你不习惯乞讨吗?我从哪里来,我乞求很多+1这是一个很好的解决方案。我没有想到保留原始索引。奇怪的是,第2步与第1步的索引排序操作完全相同,但可以在O(n)中进行鸽子洞排序。@fabrizioM-此链接似乎已断开;你能发布一个不同的链接吗?固定链接,签出postscript文件。而且这种方式是高度并行的,这就是GPU解决方案的工作方式。我刚刚开始浏览这篇文章,哇,这看起来像一个很酷的工具。我刚刚找到我下午要做的事。:-)哦,是的,绝对值得一看,值得一玩