所需交换的最小数量,因此没有数字有两个更大的邻居..?

时间:2016-03-08 19:53:49

标签: algorithm

问题陈述是这样的:给出一个N< 500 000个不同的数字,找到所需的相邻元素的最小交换数,使得没有数字具有两个更大的邻居。号码只能与邻居交换 给出提示:使用段树或fenwick树。

我真的不知道如何使用求和树来解决这个问题。

示例输入:

Input 1: 
5 (amount of elements in the list)
3 1 4 2 0

output 1: 1

input 2: 
6
4 5 2 0 1 3

output 2: 4

1 个答案:

答案 0 :(得分:1)

我可以在O(n log n)时间和O(n)额外空间中完成。但首先让我们看一下我之前提到的二次解决方案:

  • 将结果累加器初始化为0
  • ,而输入列表包含两个以上的元素

    • 找到列表中的最低元素
    • 将其距离列表较近端的距离添加到累加器
    • 从列表中删除元素。
  • 输出累加器。

为什么这样做?首先,让我们看一下需要零交换的序列如何。由于没有重复,如果最低元素在任何一端但在任何一端,它被两个元素包围,这两个元素都更大,违反了要求,因此最低元素必须位于其中一个末端。递归到排除这个元素的子序列。要使序列进入这种状态:至少需要涉及最低元素的交换,如贪婪算法需要将最低元素移动到一端,并且由于涉及最低元素的交换不会改变其余元素的相对顺序,将它们重新排序到前线也没有任何惩罚。

不幸的是,用列表实现这个是二次方的。你怎么让它更快?有一个手指树跟踪每个子树的子树权重和最小值,并在删除单个最小值时更新这些:

初始化树:首先,将列表中的每个元素视为一个元素子列表,其最小值等于其值。然后,当您有多个子列表时,将子序列成对分组,构建子序列树。序列的长度是两半长度的总和,其最小值等于两半的最小值。

在跟踪序列中的索引时从子序列中删除最小值:

  • 减少子序列的长度
  • 从最小半数等于此子序列最小值
  • 中删除最小值
  • 新的最小值是它的一半“新的最小值”
  • 中的较低者
  • 最小值的索引等于其各自一半的索引,加上左半部分的长度,如果最小值在右半部分。
  • 一端的距离等于索引或(移除前的长度 - 索引 - 1),以较低者为准。