如何为每个n构造一个算术自由置换?

时间:2019-02-03 11:31:18

标签: algorithm permutation

对于某些固定整数N,如果满足条件,则数组A[1..N]是无算术置换,

  1. A是{ 1, ... , N }的排列;和
  2. 对于每个1 ≤ i < j < k ≤ N,元素A[i]A[j]A[k](按顺序)构成算术 进展。也就是说,A[j] - A[i] ≠ A[k] - A[j]

给出一种算法,该算法在给定N的情况下,会在N的时间内返回大小为O(N log N)的无算术排列。保证所有正整数N都存在无算术置换。

2 个答案:

答案 0 :(得分:1)

bit-reversal permutation构造为下一个2的最高幂,并删除不属于该数字的数。有几种方法可以在O(n log n)时间内完成此操作。万一这是家庭作业,我将不写正式证明,但总体思路是看一下A [i],A [j]和A [k]都不相同且观察到同意的两个是相邻的。

答案 1 :(得分:0)

https://leetcode.com/articles/beautiful-array/

有一个很好的答案

a < b < cb - a = c - b。然后

2 * b = a + c

由于2 * b始终是偶数,因此要中断任何进展,ac必须具有不同的奇偶校验。但是将赔率单侧分组而另一侧则是偶数分组是不够的,因为如果我们有4个以上的数字,则可以在一组中产生算术级数。

在这里我们可以使用本文中的递归概念来打破它。我了解的一种方式是考虑,如果我们有一个数组大小为N的解,因为算术级数取决于数字之间的差异,我们可以通过算术函数将给定的解映射到相同的效果: / p>

if [a, b, c, d] works,

then [2*a, 2*b, 2*c, 2*d] works too

and so does [2*a - 1, 2*b - 1, 2*c - 1, 2*d - 1]

因此,我们要做的就是将一个较小的解决方案映射到偶数,一次映射到几率,然后分别对它们进行分组。 (将组分开将问题限制在打破每个组的算术级数上,因为我们已经证明,(a, b, c)不会依赖于不同奇偶校验的ac。 )

N1 -> [1]

N2 -> even map N1 + odd map N1
      [2*1] + [2*1 - 1]
      [2, 1]

N3 -> even map N1 + odd map N2
      [2*1] + [2*2 - 1, 2*1 - 1]
      [2, 3, 1]
...

N6 -> even map N3 + odd map N3
      [2*2, 2*3, 2*1] + [2*2 - 1, 2*3 - 1, 2*1 - 1]
      [4, 6, 2, 3, 5, 1]