解题思路:
时间复杂度和空间复杂度降到最低,并且不需要任何的辅助空间。
使用双指针,进行数组元素原地后移
假设我们使用 1 2 3 4 5 6 7 8 9 10 作为测试数据,我们需要将其变成9 10 1 2 3 4 5 6 7 8
首先我们需要两个指针i和j
原始数据: 1 2 3 4 5 6 7 8 9 10 , 这个时候指针i指向0的位置,j指向n-m也就是8这个位置,接下来我们对前m个数和后m个数对应的一一交换,1和9交换,2和10交换。
第一次交换后:指针i指向了2这个位置,而j指向索引为10的地方,由于指针j超过了数组的索引范围,我们将其重置为n-m也就是8,数组变为 9 10 3 4 5 6 7 8 1 2
第二次交换后:指针i指向了4这个位置,而j指向索引为10的地方,由于指针j超过了数组的索引范围,我们将其重置为n-m也就是8,数组变为 9 10 1 2 5 6 7 8 3 4
第三次交换后:指针i指向了6这个位置,而j指向索引为10的地方,由于指针j超过了数组的索引范围,我们将其重置为n-m也就是8,数组变为 9 10 1 2 3 4 7 8 5 6
第四次交换后:指针i指向了8这个位置,而j指向索引为10的地方,由于指针j超过了数组的索引范围,我们将其重置为n-m也就是8,数组变为 9 10 1 2 3 4 5 6 7 8,这个时候由于 i==j 指针i与j相遇,退出循环,数组后移完成。
参考代码:
#include <stdio.h>
#include <stdlib.h>
#define SWAP(a, b)((a)^=(b),(b)^=(a),(a)^=(b))
#define mal(n, t)((t *) malloc(sizeof(t) * n))
int main() {
// 输入
int n, m, *arr, i, j, k;
scanf("%d", &n);
arr = mal(n, int);
for (i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
scanf("%d", &m);
// 数组原地后移
i = 0;
j = n - m;
while (i < j) {
for (k = 0; k < m && i < j; k++) {
SWAP(arr[i], arr[j]);
i++; // i,j 指针后移
j++;
if (j == n) {
j = n - 1;
}
}
}
// 输出
for (i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
free(arr);
return 0;
}0.0分
9 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
@keheia n) { j = n - 2; } } } // 输出 for (i = 0; i < n; i++) { printf("%d ", arr[i]); } free(arr); return 0; }改成j=n-2; #include <stdio.h> #include <stdlib.h> #define SWAP(a, b)((a)^=(b),(b)^=(a),(a)^=(b)) #define mal(n, t)((t *) malloc(sizeof(t) * n)) int main() { // 输入 int n, m, *arr, i, j, k,x[10]={1,2,3,4,5,6,7,8,9,10}; // scanf("%d", &n); n=10; arr = mal(n, int); arr=x; // for (i = 0; i < n; i++) { // scanf("%d", &arr[i]); // } // scanf("%d", &m); m=2; // 数组原地后移 i = 0; j = n - m; while (i < j) { for (k = 0; k < m && i < j; k++) { SWAP(arr[i], arr[j]); i++; // i,j 指针后移 j++; if (j==