解题思路:
时间复杂度和空间复杂度降到最低,并且不需要任何的辅助空间。
使用双指针,进行数组元素原地后移
假设我们使用 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、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复