面试问题:反向对

时间:2010-10-01 05:32:17

标签: algorithm

我接受了这个采访:

如果N [i]>,则称数字是“反向排序的”。 N [j]对于i<学家 例如,在列表中:3 4 1 6 7 3,反向排序的项目是(3,1)(4,1)(4,3)(6,3)(7,3)。

如何在O(nlogn)时间内获得反向排序项目对的数量。

5 个答案:

答案 0 :(得分:18)

可以使用合并排序的修改版本在O(n log n)时间内执行此操作。除法正常,但您可以在合并时计算反转。每次从左侧列表中的项目中选择右侧列表中的项目时,会按左侧列表中剩余项目的数量递增反转计数。因此,在每个级别,反转次数是合并期间发现的反转次数加上每次递归调用所发现的反转次数。

答案 1 :(得分:4)

请注意,请阅读本答案的底部,了解为什么它实际上可以解决问题。我读错了这个问题。

在一般情况下无法实现。考虑清单:

n,n-1,n-2 ... 4,3,2,1

对将是:

(n,n-1),(n,n-2)...(n,2),(n,1),(n-1,n-2),(n-1,n- 3)......(3,2),(3,1),(2,1)

因此有O(n ^ 2)对,因此列表不能在O(n log n)中构建

但是,您可以通过列表的一次传递来执行此操作

  1. 从列表的末尾开始并使用后缀。
  2. 在列表中移动时会保留一堆你看过的数字(这会导致循环为O(n log n))
  3. 您遇到的任何号码都会在堆中搜索,以查找小于您当前所在号码的所有号码。输出堆中的当前数字和数字作为一对。 (这是O(n log n)来查找堆中的第一个匹配,但是O(n)将找到所有较小的数字)
  4. 对于您的示例

    名单:3 4 1 6 7 3

    从第二项开始

    堆(3) 第(7)项

    输出(7,3)

    堆(3,7) 第(6)项

    搜索并找到7,输出(6,3)

    堆(3,6,7) 第(1)项

    搜索并找不到任何内容

    堆(1,3,6,7) 第(4)项

    搜索并找到3和1.输出(4,3)(4,1)

    等...

    编辑,实际上可能是

    由于JoshD正确地指出我们正在寻找元素的数量,您可以使用B树而不是堆,然后您可以获得小于当前项的元素数量并将其添加到计数器。

答案 2 :(得分:0)

这可以通过创建二叉搜索树来解决,这样每​​个节点都包含其左子树的大小。

以原始数组的相反顺序将值添加到BST。保留一个总和,每次我们在添加节点时向右移动时,被比较的当前节点的左子树+ 1的大小被添加到最终总和(因为添加的值大于该节点并且其左侧的每个值子树)。

构建树是nlogn,一旦树构建,总和将是对的数量。

根据要求,需要为重复的数字添加特殊处理(即,如果(4,3)显示两次,是否应计算两次)

答案 3 :(得分:0)

从右到左的遍历,红黑树,其中每个节点通过其各自子树的大小进行扩充。因此需要O(logn)来查找给定值之下的元素数量。

答案 4 :(得分:0)

正如@jlewis42指出的那样,您可以使用合并排序的修改版本。我只想添加,您可以使用任何标准comparison sort算法,只要最坏情况下的运行时间是n log n,通过“检测”它来计算反转,因为它的工作原理。另请参阅dupe附近的this