【问题标题】:Aranging integers in a specific order按特定顺序排列整数
【发布时间】:2013-07-21 22:53:49
【问题描述】:

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

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

【问题讨论】:

  • 你的意思是s1s3s5吗?或 s1
  • 你的 C++ 问题到底是什么?
  • 你的算法到底是什么?
  • @Iuser2580076 表示 s1s3s5
  • 这个问题和这个问题重复吗? stackoverflow.com/questions/16748130/…

标签: algorithm language-agnostic


【解决方案1】:

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

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

在第一种情况下,我们知道 a

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

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

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

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

a < b > c ? d

如果 c c 且 c > d,那么我们知道 b > d。所以交换 c 和 d 得到 b > d

当您添加第五个数字时,您可以使用类似的推理。你有a &lt; b &gt; c &lt; d ? e。如果 d > e,则无需更改任何内容。如果 d

实现算法的伪代码:

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

【讨论】:

  • 有趣的是,建议的骗子有点像骗子,但公认的解决方案不如这个,13 票赞成的解决方案是 O(nlogn)
  • @aaronman 这个算法解决3,2,1,1,1,1,4,5的复杂度是多少?
  • @groovy:OP 描述的算法是 O(n)。您显示的序列不符合要求。 OP 说,“不同的未排序整数”。您的示例具有重复值。
  • @groovy 我注意到这个解决方案比你标记的欺骗中的解决方案更好
  • @aaronman 是的,看起来确实如此!尽管我仍然发现奇数/偶数数组索引的想法在开箱即用方面很有启发性。
【解决方案2】:

这是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;
}

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

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

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

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

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

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

现在你有了a &lt; b &gt; c d e,现在 d 和 e 是未知的。现在新的a,b,cc,d,e 并且您执行相同的操作,这保证不会弄乱顺序,因为c 只有在大于de 时才会更改,因此数字移入c 的点会小于b 并且不会破坏顺序,这可以无限清晰地继续,并且顺序永远不会破坏。

【讨论】:

  • 我认为他不是要代码。他在问为什么它有效。
  • @JimMischel 我写了代码,所以我能理解它为什么起作用,但看起来你已经想通了,我想通了为什么不发布它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-28
  • 2013-07-19
  • 2014-08-17
相关资源
最近更新 更多