交换具有下一个较小值的元素

时间:2011-07-27 06:31:19

标签: algorithm language-agnostic

给定一个正整数数组,当我们从左向右移动时,我们需要用小于它(当前元素)的第一个元素交换每个元素。

实施例

{ 3 , 5 , 12, 2 ,11 }
{ 2 , 3 , 5 , 11, 12 }

蛮力解决方案模拟,以便更好地理解问题

{ 5, 11, 2, 7, 2 }
After first exchange  { 2, 11, 5, 7, 2} 
After second exchange { 2, 5, 11, 7, 2}
After third exchange  { 2, 5, 7, 11, 2}
After fourth exchange { 2, 5, 7, 2, 11}

任何人都可以想到更好的O(n ^ 2)的解决方案 我首先考虑维持一个双端队列,当我们从第一个元素向右移动时,我们可以尝试维持其他元素之间的下一个最小元素。

与第一种情况一样,我会做这样的事情

while i am finding next element of 3, I will maintain a curr_next to 5. If before encountering the next small element for 3, i encounter one of 5, then I will enqueue it but it hardly improve the performance and still O(n^2)

编辑:我们必须从左向右移动。 模拟第一个例子 -

{ _3_ , 5 , 12, 2 ,11 }
{ 2,  _5- , 12, 3, 11 }
{ 2,  3, _12_ , 5, 11 }
{ 2, 3, 5, _12_,   11 }
{ 2, 3, 5,  11 ,   12 }

2 个答案:

答案 0 :(得分:4)

我可以根据Segment Trees的使用建议O(n*logn)复杂度的解决方案。

<强>算法:

  1. 构造一对数组(值,索引),它由初始数组元素的值和相应索引组成。我们称之为array_2

  2. 按值对获得的数组进行排序。

  3. 在此数组上构造Segment Tree,允许我们在给定的时间间隔内找到具有最小索引的元素。我们称之为SegmentTree

  4. 按顺序通过值数组(最初给出的值)。对于每个元素array[ i ] fing必须与之交换的元素如下:

    4.1。使用二进制搜索在array_2中查找当前元素的值。让它在某个位置k找到。在此之后array_2位置k中的所有元素都是原始数组中小于当前元素的元素。正如您稍后将看到的,它们都具有比当前索引更大的索引(因为我们将在第i步之后从i删除索引为array_2的元素)。

    4.2。现在我们必须在array_2间隔[0, k-1]找到索引最小的元素。这可以查询在步骤2中构造的SegmentTree。在我们获得具有最小索引的元素之后,我们在原始数组中执行相应的交换,在{中交换这些元素的索引 {1}}(因为它们在原始数组中已被更改)。

    4.3。对array_2执行两个更新操作 - 删除当前正在原始数组中处理索引的元素,并更新与当前处理的索引交换的元素的索引值。

  5. 执行步骤4.1 - 4.3 SegmentTree次后,我们将获得目标数组。

    <强>复杂度:

    我们通过原始数组 - n次迭代。对于每次迭代,我们执行二进制搜索 SegmentTree查询和两个 SegmentTree更新,每个更新需要n次执行。摘要logn

答案 1 :(得分:1)

问题没有说清楚。在我们交换了两个元素后,我们是否从相同的位置继续,并在没有找到更小的元素时向右移动?或者我们在交换后立即向右移动?在第一种情况下,我们最终得到一个排序数组。

在第二种情况下,我会维护一个平衡的元素和索引搜索树。从最左边的元素开始,重复这些步骤:

  1. 设置I = 0,N =长度A
  2. 循环直到我&lt; ñ
    1. 将当前元素添加到树中,其索引为
    2. 设置L = -1
    3. 重复这些步骤
      1. 在树中找到大于A [I]的最小元素。
      2. 如果存在这样的元素A [K]和K>大号
        • 在数组中交换A [I]和A [K]
        • 从树中删除A [K](它不会再被交换)
        • 更新树中新A [I]的索引
        • 设置L = K
      3. 如果没有这样的元素,请完成并增加
  3. 这种复杂性可能是O(n log n)或其他东西。这是未经测试和未经证实的,使用风险自负。