leetcode 189.旋转数组
题目描述
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入: [1,2,3,4,5,6,7] 和 k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右旋转 1 步: [7,1,2,3,4,5,6]
向右旋转 2 步: [6,7,1,2,3,4,5]
向右旋转 3 步: [5,6,7,1,2,3,4]
示例 2:
输入: [-1,-100,3,99] 和 k = 2
输出: [3,99,-1,-100]
解释:
向右旋转 1 步: [99,-1,-100,3]
向右旋转 2 步: [3,99,-1,-100]
说明:
尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
要求使用空间复杂度为 O(1) 的 原地 算法。
解题思路
方法一:按照题目的描述,一步一步的移动元素,每一步都需要O(n)的时间复杂度,这样做的话整体时间复杂度太大,所以leetcode提交会超时。(空间复杂度为O(n))
class Solution {
public:
void rotate(vector<int>& nums, int k) {
if (nums.empty()){
return ;
}
int length = nums.size();
k %= length;
while(k--){
int temp = nums[length-1];
for(int i=length-1; i>0; i--){
nums[i] = nums[i-1];
}
nums[0] = temp;
}
}
};
方法二:三次反转数组的方法,首先把整体数组反转,然后以k为分界点,两侧的数组再反转一次,就可以啦。(空间复杂度O(n))
class Solution {
public:
void rotate(vector<int>& nums, int k) {
if (nums.empty()){
return;
}
k %= nums.size();
reverseArr(nums, 0, nums.size()-1);
reverseArr(nums, 0, k-1);
reverseArr(nums, k, nums.size()-1);
}
void reverseArr(vector<int>& arr, int left, int right){
int l = left;
int r = right;
while(l<r){
int temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
l++;
r--;
}
}
};
欢迎大家关注我的个人公众号,同样的也是和该博客账号一样,专注分析技术问题,我们一起学习进步