就地一个阵列的排列遵循此规则阵列、排列、规则

由网友(断线的风筝)分享简介:假设有一个数组,我们要找出一切奇指数(指数从0开始),并将其移动到年底。在连指数都将其移动到开始。所有奇数指数项目的相对顺序和所有偶数索引项preserved。Suppose there is an array, we want to find everything in the odd index (index...

假设有一个数组,我们要找出一切奇指数(指数从0开始),并将其移动到年底。 在连指数都将其移动到开始。 所有奇数指数项目的相对顺序和所有偶数索引项preserved。

Suppose there is an array, we want to find everything in the odd index (index starting with 0), and move it to the end. Everything in the even index move it to the beginning. The relative order of all odd index items and all even index items are preserved.

即。如果阵列是

a1 b1 a2 b2 ...  an bn    

在手术后变得

after the operation it becomes

a1 a2 a3 ... an b1 b2 ... bn

这个问题能就地和O(n)的时间内完成?

Can this be done in-place and in O(n) time?

推荐答案

这是可能的,但它是非常复杂的!更简单的O(nlogn)和O(​​1)空间的解决方案可能会更好code和缓存中的条款。

It is possible, but it is very complicated! A simpler O(nlogn) and O(1) space solution might be better to code and in terms of cache.

我们将解决你的不同问题,但你的问题是微不足道的解决,一旦我们解决这个问题。

We will solve a problem different from yours, but your problem is trivial to solve once we solve that problem.

考虑阵列是

b1, a1, b2, a2, ..., bn, an

,你必须将其转换为

and you have to convert this to

a1, a2, ..., an, b1, b2, ..., bn

与索引工作1至2N,

Working with indices 1 to 2n,

我们可以看到,这是由

i -> (n+1)*i (mod 2n+1).

的O(nlogn)时间为O(1)空间解

我们可以使用分而治之,如下所示。

We can use divide and conquer as follows.

首先为几μm接近N / 2转换

First for some m close to n/2 convert

B1,A1,...,BN,一个

a1,a2,...am, b1,b2, ..bm, a(m+1), ..., an, b(m+1), ... , bn

通过递归地施加到第一2米元件,然后将剩余

by recursively applying to first 2m elements, and then the remaining.

现在我们需要做的这个循环移位由M点的中间阵列(这可以在O(n)时间及O(1)空间来完成)

Now all we need to do this cyclic shift the middle array by m spots (this can be done in O(n) time and O(1) space)

a1, a2, .., am , a(m+1), ..., an, b1, b2, ..., bm, b(m+1), ..., bn.

当然,作为IVlad指出,这需要O(LOGN)堆栈空间。我们可以通过这样做解决了以下内容:

Of course, as IVlad pointed out, this needs O(logn) stack space. We can get around that by doing the following:

我们有:

b1 a1, b2 a2, .. bm am, b(m+1) a(m+1), ..., bn an

现在换对数组的后半部分给

Now swap pairs in the latter part of the array to give

b1 a1, b2 a2, .. bm am, a(m+1) b(m+1), ..., an bn

现在循环移位在奇数位置上的元素: B1,B2,...,BM,一个(M + 1),(M + 2)...,第(N)

Now cyclic shift the elements at odd position: b1, b2, .., bm, a(m+1), a(m+2) ..., a(n).

这给了像

a(m+1) a1, a(m+2) a2, ..., a(2m) am, a(2m+1) b(m+1),...,an b(n-m), b1 b(n-m+1),...,bm bn

现在再次交换阵列的后半部分给

Now again swap the latter part of the array to give

a(m+1) a1, a(m+2) a2, ..., a(2m) am, b(m+1) a(2m+1),...,b(n-m) an,b(n-m+1) b1,..., bn bm

现在递归求解所述第一部分和第二部分,得到

Now recursively solve the first part and second part to give

[a1 a2 ... am][a(m+1) ... a(2m)]   [a(2m+1) ...an b1 b2 .. bm][b(m+1) ... bn]

这工作是否2米> = n或没有。

This works whether 2m >= n or not.

所以,这是O(nlogn)时间和O(1)空间算法。

So, this is O(nlogn) time and O(1) space algorithm.

的O(n)时间O(1)空间的解决方案。

使用的想法类似于下面的文章中使用的思路: 一个简单的原地算法为Inshuffle 。

The ideas used are similar to the ideas used in the following paper: A simple in-place algorithm for Inshuffle.

您将需要阅读的文件,了解以下。我建议你​​也阅读:http://stackoverflow.com/questions/2352542/how-to-master-in-place-array-modification-algorithms

You would need to read that paper to understand the below. I suggest you also read: http://stackoverflow.com/questions/2352542/how-to-master-in-place-array-modification-algorithms

这基本上是什么解决在上面的纸的逆置换。

This is basically the inverse permutation of what is solved in the paper above.

这是足以解决这个问题时,2N + 1的3 =功率(3 ^ M说),因为我们可以使用分而之后征服(如O(nlogn)解决方案)。

It is enough to solve this when 2n+1 is a power of 3 = (3^m say), as we can use divide and conquer after that (like the O(nlogn) solution).

现在2N + 1和N + 1互质,所以工作模3 ^ M,我们看到,N + 1的必须的是2一些权力(再请参阅本文明白为什么:基本上任何数量的模3 ^ m,是互质3 ^ m为2的幂,再次模3 ^米)

Now 2n+1 and n+1 are relatively prime, so working modulo 3^m, we see that n+1 must be some power of 2. (See that paper again to see why: basically any number modulo 3^m which is relative prime to 3^m is a power of 2, again modulo 3^m).

说N + 1 = 2 ^ K(我们不知道ķ但,请注意,这是模3 ^ M)。

Say n+1 = 2^k (we don't know k yet and note this is modulo 3^m).

一个办法,找出K,对N + 1模3 ^ M计算的权力,直到它变成1。这为我们提供了K(和为O(n)的时间最多)。

A way to find out k, compute powers of n+1 modulo 3^m, till it becomes 1. This gives us k (and is O(n) time at most).

现在我们可以看到,在置换的周期(参见上述纸/计算器链接那是什么)开始

Now we can see that the cycles of the permutation (see above paper/stackoverflow link for what that is) start at

2 ^一* 3 ^ B

2^a*3^b

其中0℃= A LT; k,以及0℃= b将米

where 0 <= a < k, and 0 <= b < m.

所以,你开始每个可能对(A,B),并按照排列的循环,这给出了一个O(n)的时间,原地算法,触碰每个元素并不比固定数量多倍!

So you start with each possible pair (a,b) and follow the cycles of the permutation, and this gives an O(n) time, in-place algorithm, as you touch each element no more than a constant number of times!

这是一个有点短暂的(!),如果你需要更多的信息,请让我知道。

This was a bit brief(!) and if you need more info, please let me know.

阅读全文

相关推荐

最新文章