提问者:小点点

如何为每个n构造一个算术自由排列?


对于一些固定整数N,数组A[1… N]是无算术排列,如果

  1. A是{1,…, N}的排列;和
  2. 对于每个1≤i

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


共2个答案

匿名用户

构造2的下一个最高幂的位反转排列,并删除不属于的数字。在O(n log n)时间内有几种方法可以做到这一点。如果这是家庭作业,我不会写一个正式的证明,但总的想法是查看A[i]、A[j]和A[k]不完全相同的最低阶位,并观察同意的两个相邻。

匿名用户

https://leetcode.com/articles/beautiful-array/有很好的答案

a

2 * b = a + c

由于2*b始终是偶数,因此要中断任何级数,ac必须具有不同的奇偶校验。但是将赔率分组到一边,将偶数分组到另一边是不够的,因为如果我们有超过4个数字,我们可以在其中一个组中生成算术级数。

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

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]