两种写法思路:
思路一:三次倒置
前言:C/C++函数 reverse 是 左闭右开区间的,作用是将指定范围数组元素全部倒置,数组从 0 开始,这里主要讲解思路,就直接用 函数 reverse 简化过程
这个方法 实现 时间复杂度为 O(n) 空间复杂度为 O(n) (空间复杂度包括 数组 arr)reverse(arr.begin(), arr.begin()+n);reverse(arr.begin(), arr.begin() + k);reverse(arr.begin() + k, arr.begin() + n);
思路:先把 数组 arr 全部倒置,再把 前 k 个元素 倒置,最后再把 从 k+1 ~ n-1 的 元素倒置(也就是剩下的元素)
1.首先,将整个数组 arr 进行反转。即将数组 arr 中的元素 arr[0] 至 arr[n-1] 倒序排列。
例如,数组 arr 为[1, 2, 3, 4, 5],反转后的数组 arr 为 [5, 4, 3, 2, 1]。
2.接下来,将数组an的前k个元素进行反转。
例如,数组 arr 为[5, 4, 3, 2, 1],k 为 2,则反转后的数组an为[4,5,3,2,1]。
3.再然后,将数组an的后n-k个元素进行反转。
例如,数组 arr 为[4, 5, 3, 2, 1],n 为 5,k 为 2,则反转后的数组an为[4, 5, 1, 2, 3]。
思路二:本质在 题目说 元素向右移动 k 位,等价于 元素向左移动 n - k 位
int t = 0; // 利用题目给的:只用一个元素大小的附加存储 for (int i = 0; i < n - k; ++i) { // n - k 次t = arr[0]; // 每次保存 首位元素for (int j = 0; j < n; ++j) { // 每轮 元素向左 移动一位:这样会覆盖 第一个元素,则 变量 t 作用就体现出来了:保存每轮首位元素arr[j] = arr[j + 1];}arr[n - 1] = t; // 将最后一个位置 放上 t :代表每轮第一个元素 到了 最后,实现移动 }
但是 思路二 的时间复杂度是 O(nk) 好像不符合题目,所以我就写了 思路一 作为 我的正解,本思路作为 拓展
具体代码实现:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 100;
int n, k;
vector<int>arr(N); // C++的向量容器:类似C语言的数组signed main()
{ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);cin >> n >> k;// 初始化数组为 1 2 3 4 5for (int i = 0; i < n; ++i) {arr[i] = i + 1;}// 思路一:三次倒置reverse(arr.begin(), arr.begin()+n);reverse(arr.begin(), arr.begin() + k);reverse(arr.begin() + k, arr.begin() + n);// 思路二:本质:题目说 元素向右移动 k 位,等价于 元素向左移动 n - k 位int t = 0; // 利用题目给的:只用一个元素大小的附加存储for (int i = 0; i < n - k; ++i) { // n - k 次t = arr[0]; // 每次保存 首位元素for (int j = 0; j < n; ++j) { // 每轮 元素向左 移动一位:这样会覆盖 第一个元素,则 变量 t 作用就体现出来了:保存每轮首位元素arr[j] = arr[j + 1];}arr[n - 1] = t; // 将最后一个位置 放上 t :代表每轮第一个元素 到了 最后,实现移动}for (int i = 0; i < n; ++i) {cout << arr[i] << ' ';}return 0;
}
【若文章有什么错误,欢迎评论区讨论或私信指出】