LeetCode189.旋转数组

旋转数组

题目描述

给定一个数组,将数组中的元素向右移动 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) 的 原地 算法。

思路1

每次向后移动一位,循环移动K次,即可达到将数组中的元素向右移动 k 个位置的效果但是好像超出时间限制

代码实现

void rotate(vector<int>& nums, int k) {
        int length = nums.size();
        k %= length;
        if(k == 0) {return;}//如果k等于0或者k原本是等于len的,那么就相当于没有移动嘛,直接返回
        //每次往后移一位,移动k次
        for(int i = 0; i < k; ++i){
            int temp = nums[length - 1];
            for(int j = length - 1; j > 0; --j){
                nums[j] = nums[j-1];
            }
            nums[0] = temp;
        }
    }

思路2

不再是每次循环1位,循环移动K次,直接一次移动到位,可以在O(n)时间完成,不过需要额外的k个空间保存元素即先将最后k个元素保存,因为下面移动将覆盖,然后直接一次移动k位放到正确位置,最后将最后k个元素放到最初正确位置

代码实现

void rotate(vector<int>& nums, int k){
        int length = nums.size();
        k %= length;
        if(k == 0) {return;}//如果k等于0或者k原本是等于len的,那么就相当于没有移动嘛,直接返回
        int tmp[k];
        for(int i = 0; i < k; ++i){//先将最后k个元素保存,因为下面移动将覆盖
            tmp[i] = nums[length - k + i];
        }
        for(int i = length-1; i >= k; --i){//直接一次移动k位
            nums[i] = nums[i - k];
        }
        for(int i = 0; i < k; ++i){//将最后k个元素放到最初正确位置
            nums[i] = tmp[i];
        }
    }

思路3

申请一个额外的数组,用来保存移动后的元素,不过这种方法时间复杂度O(n),空间复杂度O(n),最后将全部移动后的元素复制原数组

代码实现

void rotate(vector<int>& nums, int k){
        int length = nums.size();
         k %= length;
         if(k == 0) {return;}//如果k等于0或者k原本是等于len的,那么就相当于没有移动嘛,直接返回
         int tmp[length]; //额外申请一个数组,保存移动后元素
         for(int i = 0; i < length; ++i){
            tmp[(i+k)%length] = nums[i];
         }
         for(int i = 0; i < length; ++i){
             nums[i] = tmp[i];
         }
    }
上一篇:正则表达式编译==> re.compile()


下一篇:gradle中 使用lombok