开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 13 天,点击查看活动详情
Day41 2023/02/16
难度:简单
题目
示例
输入:arr = {0, 1, 2, 3, 4}; p=3
输出:arr = {3, 4, 0, 1, 2}
思路
要尽可能的高效的时间和空间复杂度,所以这里最好使用逆序的方式来解题,我们可以先将数组原地逆序,再将前n-p个元素逆序,最后在将后p个元素逆序即可。 例如:arr = {0, 1, 2, 3, 4}; p =3
具体步骤:
- 数组原地逆序得到:arr = {4, 3, 2, 1, 0}
- 前2个元素逆序的:arr = {3, 4, 2, 1, 0}
- 最后三个元素逆序: arr = {3, 4, 0, 1, 2}
关键点
- 因为reverse方法中传入的left,right是数组下标,所以要在数组长度n(位序)的基础上减1
算法实现
c++代码实现- 多次逆序
#include <bits/types/struct_tm.h>
#include <iostream>
#include <vector>
using namespace std;
//将数组[left, right]范围内的元素逆序
void reverse(vector<int> &arr, int left, int right) {
int tmp; // 中间变量
while (left < right) {
tmp = arr[left];
arr[left++] = arr[right];
arr[right--] = tmp;
// left++;
// right--;
}
}
// 把数组元素向左移动p个位置
int ArrayToShiftLeft(vector<int> &arr, int p) {
int n = arr.size();
if (p <= 0 || p >= n || n <= 1)
return 0; //非法情况
reverse(arr, 0, n - 1); //数组整体逆转
reverse(arr, 0, n - p - 1); //前n-p个元素逆转
reverse(arr, n - p, n - 1); // 后p个元素逆转
return 1;
}
int main() {
//测试以下
vector<int> arr = {0, 1, 2, 3, 4};
if (ArrayToShiftLeft(arr, 3)) { //防止非法输入
//便利打印数组
for (auto it : arr) {
cout << "向左平移3为后的数组:" << it;
}
return 0;
}
}
- 时间复杂度 --- 遍历了数组接近2次,其中n为数组长度
- 空间复杂度 --- 没有额外的辅助空间
总结
- 这题在不考虑最好时间和空间复杂度的情况下,还可以使用辅助数组的方式,快速的解题。