如何找到数组中每个元素的等级,在关系的情况下平均有效?例如:
float[] rank(T)(T[] input) {
// Implementation
}
auto foo = rank([3,6,4,2,2]); // foo == [3, 5, 4, 1.5, 1.5]
我能想到的唯一方法是分配3个数组:
有没有人知道如何在O(N log N)时间和O(1)辅助空间中执行此操作(意味着我们必须分配的唯一数组是我们要返回的数组),或者至少摆脱它上面三个阵列中的一个?
答案 0 :(得分:4)
您可以分配要返回的数组(让我们称之为R),将其初始化为0..n-1然后“排序”传入的数组(称为I),但使用比较I [R [k ]]与I [R [j]]相比,而不是正常的R [k]与R [j],然后根据需要交换R数组中的值(而不是像往常一样交换I数组中的值)。 / p>
你可以使用quicksort或heapsort(或bubblesort)来实现这种间接排序,但这会破坏你的复杂性。
您只需要分配一个数组 - 并为索引分配一些堆栈空间。
答案 1 :(得分:2)
好的,所以你将输入数组复制到foo
。使用heapsort在O(n log n)时间内就地foo
排序。现在,取出输入数组的第一个元素,并使用binary search在O(log n)时间内在foo
中找到它的等级,并将等级插入ranks
数组并返回它。 / p>
现在,您使用2个数组而不是3个。
答案 2 :(得分:0)
如果你不拥有数组,我认为不可能在O(N log N)和空间O(1)中进行。
如果元素的范围(元素的大小)很小,则使用计数。计算每个元素的数量,然后使用计数数组基于输入数组计算结果数组。
c - is counting result,
C - is cumulative counting
C[i] = c[i] + c[i-1] + c[i-2] + ... + c[0]
result[i] = 1 / c[in[i]] + C[in[i]-1]
答案 3 :(得分:0)
为什么不只是复制和排序数组并从那里开始?有许多可用的就地排序算法,例如heapsort。
答案 4 :(得分:0)
用一些简单的代码总结florin's answer(和相关的注释)可能会有用。
以下是如何在Ruby中执行此操作:
arr = [5,1,0,3,2,4]
ranks = (0..arr.length-1).to_a.sort_by{ |x| arr[x] }
# ranks => [2, 1, 4, 3, 5, 0]
在Python中:
arr = [5,1,0,3,2,4]
ranks = range(len(arr))
ranks.sort(key=lambda x:arr[x])
# ranks => [2, 1, 4, 3, 5, 0]
rank数组告诉你0有2级,1有1级,2有4级等等(当然,那些级别从0开始,不是1级。)
答案 5 :(得分:0)
如何使用二进制搜索树并逐个将元素插入到该BST中。然后可以通过在我们想要找到使用顺序遍历BST的元素节点左侧出现的所有元素上保持一个计数器来确定排名。
答案 6 :(得分:0)
我已经使用它在python中快速而又脏了:
def rank(X):
B = X[:]
B.sort()
return [ float(B.index(x)+1) for x in X]
def rank(X):
B = X[:]
B = list(set(B))
B.sort()
return [ float(B.index(x)+1) for x in X]
第一个示例适用于您在原始列表中没有重复项的情况。它可以做得更好,但我正在玩一些黑客并且出来了。如果你有重复的话,第二个就可以了。