问题:设计一个算法,把一个含有N个元素的数组循环右移K位,要求时间复杂度为O(N),且只允许使用两个附加变量。
方法1.思路:移位可以看成是字符串的翻转。
(1)将一个字符串abcdef分成两部分:X:abc, Y:def
(2)X/Y翻转:X->X^T,即abc->cba;Y->Y^T,即def->fed。得到cbafed。
(3)整个翻转:(X^TY^T)^T=YX,得到defabc。
解答:右移字符串
#include <stdio.h>
Reverse(char* arr,int b,int e){
for(;b<e;b++,e--){
int temp=arr[e];
arr[e]=arr[b];
arr[b]=temp;
printf("%d: %s\n",b,arr);
}
}
RightShift(char* arr,int N,int K){
K%=N; //因为有可能会出现K>N,这种情况下右移K-N次与右移K次的效果是相同的
Reverse(arr,0,N-K-1); //如果是左移,就写成Reverse(arr,0,K-1);
Reverse(arr,N-K,N-1); //Reverse(arr,K,N-1);
Reverse(arr,0,N-1);
}
int main(){
int N=0,K=0;
char s[100];
// memset(s,'0',sizeof(char)*100);
scanf("%s%d",s,&K);
N = strlen(s);
RightShift(s,N,K);
printf("%s\n",s);
return 0;
}
1.将要移位的字符串存放在另外的数组p中;
2.将目的字符数组a中的字符进行移位;
3.将数组p中字符赋给数组a。
实现代码如下:
实现代码如下:
/*
*Author:cbjust
*Date:2013-01-10
*
*/
#include <stdio.h>
#include <string.h>
//左移
void leftShift(char a[],int N,int K){
int i;
char p[1001];
memset(p,'0',sizeof(p));
//将数组a中要移位的字符串存放在数组p中
for(i=0;i<K;i++){
p[i] = a[i];
}
//将数组a中元素前移K个位置
for(i=0;i<N-K;i++){
a[i] = a[i+K];
}
//将数组p中元素赋值给数组a
for(i=N-K;i<N;i++){
a[i]=p[i-N+K];
}
}
//右移
void rightShift(char a[],int N,int K){
int i;
char p[1001];
memset(p,'0',sizeof(p));
//将数组a中要移位的字符串存放在数组p中
for(i=0;i<K;i++){
p[i] = a[i+N-K];
}
//将数组a中元素后移K个位置
for(i=0;i<N-K;i++){
a[N-1-i] = a[N-1-i-K];
}
//将数组p中元素赋值给数组a
for(i=0;i<K;i++){
a[i]=p[i];
}
}
int main(){
char a[1001];
int K,N;
scanf("%s%d",a,&K);
N = strlen(a);
// leftShift(a,N,K);
// printf("%s\n",a);
rightShift(a,N,K);
printf("%s\n",a);
return 0;
}方法2相比方法1,只是增加了数组p的开销~时间复杂度依然为O(n)
本文探讨如何设计一个算法,在O(N)的时间复杂度内,仅使用两个额外变量,将一个包含N个元素的数组进行K位的循环右移操作。这种算法对于处理大规模数据时的效率至关重要。
306

被折叠的 条评论
为什么被折叠?



