题目:
给定一个数组,将数组中的元素向右移动 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]
思路:
比较浅显的就是提供一个只移动一位的接口,通过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。真的很巧妙呢。