旋转数组---简单

题目:

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

示例:

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

思路:

  比较浅显的就是提供一个只移动一位的接口,通过k取余数组的长度来得到最终的移动位数。然而这种做法的时间复杂度为O(kn),暂时想不出简单的解法,先试试看吧。

void rotate_one_step(vector<int>& nums)
{
    int temp=std::move(nums[nums.size()-1]);
    for(int i=nums.size()-1;i>=1;--i)
    {
        nums[i]=std::move(nums[i-1]);
    }
    nums[0]=std::move(temp);
}

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

  我们可以看到:虽然通过了,可结果惨不忍睹呢。来看看大佬的解法吧:

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        int len = nums.size();
        k %= len;
        reverse(nums, 0, len - 1);
        reverse(nums, 0, k - 1);
        reverse(nums, k, len - 1);
    }
    void reverse(vector<int>& nums, int start, int end) {
        while (start < end) {
            int temp = nums[start];
            nums[start++] = nums[end];
            nums[end--] = temp;
        }
    }
};

  可以看到,大佬采用了逆序的方法呢,使得复杂的降到O(n)。比如先前的示例,先对整个数组逆序为7654321。然后在分段逆序,对前面三个数逆序后567,对后四个逆序后1234,最后就是5671234。真的很巧妙呢。

原文地址:https://www.cnblogs.com/manch1n/p/10305008.html