有个长度为2n的数组{a1,a2,a3,...,an,b1,b2,b3,...,bn},希望排序后{a1,b1,a2,b2,....,an,bn},请考虑有无时间复杂度o(n),空间复杂度0(1)的解法。
#include <iostream>
using namespace std;
//翻转字符串时间复杂度O(to - from)
void reverse(int *a, int from, int to) {
int t;
for (; from < to; ++from, --to) {
t = a[from];
a[from] = a[to];
a[to] = t;
}
}
//循环右移num位 时间复杂度O(n)
void RightRotate(int *a, int num, int n) {
reverse(a, 1, n - num);
reverse(a, n - num + 1, n);
reverse(a, 1, n);
}
/*领悟版:时间O(n),空间O(1)
* 原理:
*逐一处理序列对:
*将当前序列对凑在一起:
*将未处理序列的头元素与当前处理的序列对次元素换位(实际上是换位算法变形)
例:(1234)(5678)各一叠
1 2 3 4 5 6 7 8 未处理序列对:4
第一次:
1 5 2 3 4 6 7 8 未处理序列对:3
第二次:
1 5 2 6 3 4 7 8
...
* */
void perfectShuffle(int* a, int n) {
while (n > 0) {
RightRotate(a + 1, 1, n);
a += 2;
n--;
}
}
//时间复杂度O(n),空间复杂度O(1),数组下标从1开始,调用perfect_shuffle3
void shuffle(int *a, int n) {
int i, t, n2 = n * 2;
PerfectShuffle2(a, n);
for (i = 2; i <= n2; i += 2) {
t = a[i - 1];
a[i - 1] = a[i];
a[i] = t;
}
}