在一个数组/列表中,排名一个元素x就是找出在这个数组/列表中比x小的元素总数。
因此,对一个列表进行排名就是获得列表中所有元素的排名。
例如,排名[51, 38, 29, 51, 63, 38] = [3, 1, 0, 3, 5, 1],即51有3个比它小的元素,等等。
对列表进行排名可以在O(NlogN)的时间内完成。基本上,我们可以对列表进行排序,同时记下每个元素的原始索引,然后看看每个元素之前有多少个元素。
问题在于如何以O(NlogN)的时间对列表的后缀进行排名?
排列一个列表的后缀意味着:
对于列表[3;1;2],排名[[3;1;2];[1;2];[2]]
请注意,元素可能不是唯一的。
我们不需要为所有后缀打印出所有元素。你可以想象我们只需要打印出一个列表/数组,其中每个元素都是一个后缀的排名。
例如,rank suffix_of_[3;1;2] = rank [[3;1;2]; [1;2]; [2]] = [2;0;1],你只需要打印出[2;0;1]。
让我更清楚地解释一下什么是“所有后缀”以及什么意思是“对所有后缀进行排序/排名”。
假设我们有一个数组/列表[e1;e2;e3;e4;e5]。
那么[e1;e2;e3;e4;e5]的所有后缀是:
[e1;e2;e3;e4;e5]
[e2;e3;e4;e5]
[e3;e4;e5]
[e4;e5]
[e5]
例如,[4;2;3;1;0]的所有后缀是
[4;2;3;1;0]
[2;3;1;0]
[3;1;0]
[1;0]
[0]
对以上5个后缀进行排序意味着按字典顺序排序。对所有这些后缀进行排序,您将得到
[0]
[1;0]
[2;3;1;0]
[3;1;0]
[4;2;3;1;0]
因此,对一个列表进行排名就是获得列表中所有元素的排名。
例如,排名[51, 38, 29, 51, 63, 38] = [3, 1, 0, 3, 5, 1],即51有3个比它小的元素,等等。
对列表进行排名可以在O(NlogN)的时间内完成。基本上,我们可以对列表进行排序,同时记下每个元素的原始索引,然后看看每个元素之前有多少个元素。
问题在于如何以O(NlogN)的时间对列表的后缀进行排名?
排列一个列表的后缀意味着:
对于列表[3;1;2],排名[[3;1;2];[1;2];[2]]
请注意,元素可能不是唯一的。
我们不需要为所有后缀打印出所有元素。你可以想象我们只需要打印出一个列表/数组,其中每个元素都是一个后缀的排名。
例如,rank suffix_of_[3;1;2] = rank [[3;1;2]; [1;2]; [2]] = [2;0;1],你只需要打印出[2;0;1]。
让我更清楚地解释一下什么是“所有后缀”以及什么意思是“对所有后缀进行排序/排名”。
假设我们有一个数组/列表[e1;e2;e3;e4;e5]。
那么[e1;e2;e3;e4;e5]的所有后缀是:
[e1;e2;e3;e4;e5]
[e2;e3;e4;e5]
[e3;e4;e5]
[e4;e5]
[e5]
例如,[4;2;3;1;0]的所有后缀是
[4;2;3;1;0]
[2;3;1;0]
[3;1;0]
[1;0]
[0]
对以上5个后缀进行排序意味着按字典顺序排序。对所有这些后缀进行排序,您将得到
[0]
[1;0]
[2;3;1;0]
[3;1;0]
[4;2;3;1;0]
顺便提一下,如果你无法想象五个列表/数组如何在它们之间排序,可以考虑按词典顺序排序字符串。
"0" < "10" < "2310" < "310" < "42310"
似乎对所有后缀进行排序实际上是对原始数组的所有元素进行排序。
但是,请注意所有元素可能不是唯一的,例如
对于 [4;2;2;1;0],所有后缀为:
[4;2;2;1;0]
[2;2;1;0]
[2;1;0]
[1;0]
[0]
然后按以下顺序排列:
[0]
[1;0]
[2;1;0]
[2;2;1;0]
[4;2;2;1;0]