旋转数组-LeetCode

题目来源:

https://leetcode-cn.com/problems/rotate-array/description/


描述:

给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。


示例:

输入: [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]


思路:

思路一:

参考示例,利用vector特性,只需要将7,6,5依次插入vector首部即可。这个涉及内存再分配,很耗时间的.

思路二:

很经典的思路,数组整体移动考虑用数组反转,还是上述示例
第一步:反转前几位 [4,3,2,1,5,6,7]
第二步:反转整个数组[7,6,5,1,2,3,4]
第三步:反转前几位 [5,6,7,1,2,3,4]

思路三:

还是用参考示例,来[1,2,3,4,5,6,7]向右移动三位的话,首先元素1占据元素4的位置,然后元素2占据了元素5的位置。这样需要新数组能暂存4,5,6,7的值。需要o(n)个变量来暂存。 此时,如何做到只用一个变量暂存呢?
[1,2,3,4,5,6,7]
[1,2,3,1,5,6,7] 把元素4暂存
这里是重点,只用一个变量暂存!方法就是把元素4填入新的位置,然后再暂存新元素
[1,2,3,1,5,6,4] 把4放入新位置,4就可以不暂存了,变量直接存储新元素7.然后依次类推。

什么时候截止?由于每个元素都要移动一次,所以循环n次(n为数组大小)
这样就结束了吗?考虑一种情况,举例[1,2,3,4,5,6]向右移动2个位置
[1,2,3,4,5,6]
[1,2,1,4,5,6]暂存3
[1,2,1,4,3,6]暂存5
[5,2,1,4,3,6]暂存1
继续移动发现一直是1,3,5三个元素在移动。所以当移动开头位置时,向后跳一格,2所在位置作为新开头位置。对2进行新循环移动
[5,2,1,2,3,6]暂存4
[5,2,1,2,3,4]暂存6
[5,6,1,2,3,4]暂存2 。 此时移动了6次,总循环结束。


代码:

思路一:

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        size_t size = nums.size();
        if (size == 0) return;

        for (int i = 0; i < k%size; ++i) {
            nums.insert(nums.begin(),nums[size - 1]);
        }
        nums.resize(size);
    }
};

思路二:

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        size_t size = nums.size();
        if (size == 0) return;
        k %= size;
        if (k == 0) return;

        reverse(nums,0,size-1-k);
        reverse(nums,0,size-1);
        reverse(nums,0,k-1);
    }

    //对数组中位置i和j之间的所有元素进行反转[i,j]
    void reverse(vector<int>& nums,int i,int j){
        int size = nums.size();
        if (i < 0 || i >= size || j < 0 || j >=size) return;
        while (i < j){
            int temp = nums[i];
            nums[i++] = nums[j];
            nums[j--] = temp;
        }
    }
};

思路三:

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        int begin = 0;
        int step = 0;
        int i = 0;
        int cur;
        int bak = nums[0];

        size_t size= nums.size();
        while(step++ < size){
            i = (i + k) % size;
            cur = bak;          
            bak = nums[i];
            nums[i] = cur;
            if (i == begin){
                begin++;
                i++;
                bak = nums[i];
            }
        }
    }

};

猜你喜欢

转载自blog.csdn.net/wolf_break/article/details/81145583