Rotate Array -- leetcode

Rotate an array of n elements to the right by k steps.

For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4].

Note:
Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem.

[show hint]

Related problem: Reverse Words in a String II

基本思路一:

设立一个后备容器,将最后的k个元素移入后备容器中。

然后再将原数组吐剩余元素整体向移动k个位置。

最后将后备容器中保存的元素,覆盖到原数组的头部。

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        const int n = nums.size();
        k %= n;
        vector<int> backup(nums.end()-k, nums.end());
        for (int i=n-1; i>=k; i--)
            nums[i] = nums[i-k];
            
        for (int i=0; i<k; i++)
            nums[i] = backup[i];
    }
};

此算法的空间复杂度为O(n),不满足题目要求。


基本思路二:

数组末尾的k个元素,在移动完成后,将位于数组头部。

将数组头部k个元素与尾部k个元素,进行交换。 

交换后,数组前k个位置已经处于最终结果。 只需要于处理数组余下部分。

忽略此头部的k个元素,将得到一个新数组。

而新数组中,继续将数组头k个元素与尾部k个元素进行交换。 

则新数组的前k个元素处于最终结果。只需要处理数组余下部分。

如此重复下去。

概括起来,就是将数组末尾k个部分,作为中转。

要注意的事,收敛条件:  当数组剩余元素的个数,小于k时。 此时需要取余。

循环直到,余数为0,即不需要移动。

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        int n = nums.size();
        k %= n;
        auto iter = nums.begin();
        while (k) {
            for (int i=0; i<k; i++) {
                swap(*iter++, *(nums.end()-k+i));
            }
            n -= k;
            k %= n;
        }
    }
};


基本思路三:

数组向后移动k步。只需要把数组尾部k个元素,移动数组头部。而其余元素顺序向后移动k个位置。

先进行数组整体反转。 这样,原数组后部的k个元素将位于数组前面k个位置。 但顺序是刚相反的。

对数组前k个位置进行反转。 将达到的期望顺序。 至此,数组最后的k个元素移动完成。

而此时,剩余的n-k个位置,也达到预定位置。只是与最终结果不同的是,顺序刚好相反。

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        k %= nums.size();
        reverse(nums.begin(), nums.end());
        reverse(nums.begin(), nums.begin()+k);
        reverse(nums.begin()+k, nums.end());
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值