置换数组使其在增加和减少之间交替

时间:2014-12-13 00:55:07

标签: arrays algorithm

  

如果在增加和减少之间交替,则不同整数的数组X [1..n]是 摇摆 :X [i]<每个奇数索引 i 的X [i + 1],以及X [i]>每个偶数索引 i 的X [i + 1]。例如,以下16元素数组摇摆不定:

12,13,0,16,13,31,5,7,-1,23,8,10,-4,37,17,42

  

描述和分析一种算法,该算法可以置换给定数组的元素,使数组不稳定。

我的尝试:

更明显的解决方案是将原始数组排序,将其拆分为一半,然后在每个子数组之间交替,抓取数组中的第一个元素以创建抖动数组。这需要O(nlogn)。 (编辑:刚刚意识到这只有在所有整数都不同的情况下才有效。)我不能帮助,但认为有更有效的方法来实现这一目标。

怎么可以这样做?

(这不是家庭作业问题)

2 个答案:

答案 0 :(得分:1)

我能想到的这种最直接的方法是对数组进行排序,然后在获取最低和最高剩余元素之间交替。

E.g。使用您的示例列表,已排序:

-4 -1 0 5 7 8 10 12 13 13 16 17 23 31 37 42

结果变为

-4 42 -1 37 0 31 5 23 7 17 8 16 10 13 12 13

但是,如果你在中间有相同的元素,我认为这会破坏,因此在这种情况下你可能需要在序列结束时进行一些手动值替换以恢复"摇摇晃晃&#34 ;约束

答案 1 :(得分:1)

[3年后......: - )]

您的问题定义指出所有数组元素都是不同的。所以,你可以做得比排序更好 - 排序做得太多了。

请注意,您有第一个k元素构建的 摇摆 序列。序列中的最后两个元素可以有两种情况:

  1. A[k-1] < A[k]
  2. A[k-1] > A[k]
  3. 案例1 :如果A[k+1] < A[k],则您无需执行任何操作,因为已经维护了 wobbliness 。但是,如果A[k+1] > A[k],交换它们将确保恢复晃动。

    案例2 :如果A[k+1] > A[k],您无需执行任何操作,因为已经保持了晃动。但是,如果A[k+1] < A[k],交换它们将确保恢复晃动。

    这会为您提供O(n)时间和O(1)空间算法(因为您正在进行交换)。你的基本情况是当k = 2时,这是非常不稳定的。

    以下是Python3中的一个实现:

    def rearrange_wobbly(A):
        if len(A) < 3:
            return A
        for i in range(2, len(A)):
            if A[i - 2] < A[i - 1] < A[i] or A[i - 2] > A[i - 1] > A[i]:
                # Swap A[i] and A[i - 1]
                A[i - 1], A[i] = A[i], A[i - 1]
    
    >>> A = [x for x in range(10)]
    >>> A
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    >>> random.shuffle(A)
    >>> A
    [3, 2, 1, 0, 7, 6, 9, 8, 4, 5]
    >>> rearrange_wobbly(A)
    >>> A
    [3, 1, 2, 0, 7, 6, 9, 4, 8, 5]