设a[0 : n-1]是一个有n个元素的数组,k(0<= k <= n - 1)是一个非负整数。
试设计一个算法将子数组a[0 : k - 1]与a[k , n - 1]换位。要求算法在最坏情况下耗时O(n),且只用到O(1)的辅助空间。
解析:使用三次翻转法:
核心代码
void reverse(int *a, int begin, int end)
{
int temp;
while(begin < end)
{
temp = a[begin];
a[begin] = a[end];
a[end] = temp;
++begin, -- end;
}
}
void PositionSwap(int *a, int k, int n)
{
//三次翻转法
reverse(a, 0, k - 1);
reverse(a, k, n - 1);
reverse(a, 0, n - 1);
}
三次翻转的流程:
①将数组a[0 : k - 1]部分翻转;
②将数组a[k : n - 1]部分翻转;
③将数组a[0 : n - 1]翻转。
举个栗子:
a[0 : 9] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, k = 5;
三次翻转分别为:
① 0~4的翻转, 翻转结果为4 3 2 1 0 5 6 7 8 9;
② 5~9的翻转,翻转结果为4 3 2 1 0 9 8 7 6 5;
③整个数组的翻转, 翻转结果为5 6 7 8 9 0 1 2 3 4;
测试样例:
10
0
1
2
3
4
5
6
7
8
9
5
输出:
5 6 7 8 9 0 1 2 3 4
代码部分:
#include <bits/stdc++.h>
using namespace std;
const int MAX = 100;
void reverse(int *a, int begin, int end)
{
int temp;
while(begin < end)
{
temp = a[begin];
a[begin] = a[end];
a[end] = temp;
++begin, -- end;
}
}
void PositionSwap(int *a, int k, int n)
{
//三次翻转法
reverse(a, 0, k - 1);
reverse(a, k, n - 1);
reverse(a, 0, n - 1);
}
void Input(int *a, int &n, int &k)
{
scanf("%d", &n);
for(int i = 0; i < n; ++i)
scanf("%d", &a[i]);
scanf("%d", &k);
}
void Printf(int *a, int n)
{
for(int i = 0; i < n; ++i)
printf("%d ", a[i]);
}
int main()
{
int n, k;
int a[MAX];
Input(a, n, k);
PositionSwap(a, k, n);
Printf(a, n);
}