按特定顺序排列整数

时间:2013-07-21 22:53:50

标签: algorithm language-agnostic

给定一组不同的未排序整数s1,s2,..,sn如何排列整数,使得s1< s2> s3< S4 ...

我知道这可以通过从左到右查看数组来解决,如果不满足条件则交换这两个元素会给出正确的答案。有人可以解释为什么这个算法有效。

2 个答案:

答案 0 :(得分:8)

给定阵列中任意三个连续数字,有四种可能的关系:

a < b < c
a < b > c
a > b < c
a > b > c

在第一种情况下,我们知道a&lt; C。由于满足第一个条件,我们可以交换b和c来满足第二个条件,并且仍然满足第一个条件。

在第二种情况下,两个条件都已满足。

在第三种情况下,我们必须交换a和b以使b

在最后一种情况下,我们知道a&gt; c,所以交换a和b以满足第一个条件可以保持第二个条件的有效性。

现在,您在序列中添加第四个数字。你有:

a < b > c ? d

如果c <那么没有必要改变任何东西。但是如果我们必须交换c和d,则仍然满足先前条件。因为如果b> c和c> d,然后我们知道b> d。所以交换c和d给我们b> d&lt;角

添加第五个数字时,您可以使用类似的推理。你有a < b > c < d ? e。如果d> e,那么就没有必要改变任何东西了。如果d&lt; e,然后根据定义c&lt; e,所以交换保持先前的条件。

实现算法的伪代码:

for i = 0 to n-2
    if i is even
        if (a[i] > a[i+1])
            swap(a[i], a[i+1])
        end if
    else
        if (a[i] < a[i+1])
            swap(a[i], a[i+1])
    end

答案 1 :(得分:1)

以下是java中建议的解决方案的代码。

public static int [] alternatingList(int [] list) {
    int first, second,third;
    for (int i = 0;i < list.length-2;i+=2) {
        first = list[i];
        second = list[i+1];
        third = list[i+2];
        if (first > second && first > third) {
            list[i+1] = first;
            list[i] = second;
        }
        else if (third> first && third > second) {
            list[i+1] = third;
            list[i+2] = second;
        }
    }
    return list;
}

在这段代码中,因为所有数字都是不同的,所以总会有更大的数字放入“峰值”。交换数字不会改变您最后一部分的一致性,因为您换出的数字总是小于您放入新峰值的数字。

请记住,这段代码不能处理一些边缘情况,比如甚至长度列表和小于三的列表,我写得很快:),我只编写代码来说明解决方案的概念

此外,这个解决方案比推荐的dupe更好,因为它可以通过一次。欺骗中的解决方案使用了hoare的选择算法,该算法是n但需要在列表中多次减小大小,并且在使用Hoare(或中位数的中位数)之后还需要在列表上再次进行n次传递。

更多数学证明:
对于每三个连续的数字a,b,c,有三个选项

a > b && a > c
b > c && b > a
c > a && c > b

在第一种情况下,你将a切换到中间,因为它是最大的,第二种情况什么都不做(最大的已经在中间),第三种情况'c`进入中间。

现在你有a < b > c d e现在d和e未知。现在,新的a,b,cc,d,e并且您执行相同的操作,这保证不会弄乱订单,因为c只有在d大于e时才会更改c因此移入b点的数字将小于{{1}}并且不会破坏排序,这可以无限地继续,顺序永不破坏。