题目
设计一个算法,把一个含有 N N N 个元素的数组循环右移 K K K 位,要求时间复杂度为 O ( N ) O(N) O(N),且只允许使用两个附加变量。
示例
输入:s = “abcd1234”, k = 4;
输出:“1234abcd”
分析
- 如果 K > N K>N K>N,右移 K K K 位之后的情形,跟右移 K ′ = K % N K' = K\%N K′=K%N之后的情形一样。
- 右移后有两段的顺序不变:
1. 逆序排列 a b c d : a b c d 1234 ⟶ d c b a 1234 abcd:abcd1234\longrightarrow dcba1234 abcd:abcd1234⟶dcba1234;
2. 逆序排列 1234 : d c b a 1234 ⟶ d c b a 4321 1234:dcba1234\longrightarrow dcba4321 1234:dcba1234⟶dcba4321;
3. 逆序排列 d c b a 4321 : ⟶ 1234 a b c d dcba4321:\longrightarrow 1234abcd dcba4321:⟶1234abcd.
实现
初级
#include<stdio.h>
#include<string.h>
void reverse(char* s, int a, int b) {
// 字符串翻转
for (; a < b; a++, b--) {
int temp = s[a];
s[a] = s[b];
s[b] = temp;
}
}
void rightShift(char* s, int N, int k) {
k = k % N;
reverse(s, 0, N - k - 1);
reverse(s, N - k, N - 1);
reverse(s, 0, N - 1);
}
int main() {
char src[] = "abcd1234";
int k = 4;
int len = strlen(src);
rightShift(src, len, k);
printf("dest = %s\n", src);
return 0;
}
进阶
// 学习 C 语言的输入输出
int main() {
char src[9];
int k;
// 输入数据
printf("Enter a string, the k\n");
scanf("%s %d", src, &k);
printf("\nsrc = %s, k =%d\n", src, k);
// 右移
int len = strlen(src);
rightShift(src, len, k);
printf("\nrightShift dest = %s \n", src);
return 0;
}
知识点
- 在读取字符串时,只要遇到一个空格,scanf() 就会停止读取