苏州做网站推广河北疫情最新情况
这道题我也没想到特别好的解法,直接用最笨的解法AC了,首先k可能会远超数组nums
的大小,这就意味着可能会出现多次无效轮转,因此我们先对次数k进行剪枝,k = k % nums.size()
来减少不必要的轮转次数,然后我们定义一个数组v
用于存储从数组后端轮转到前端的元素,例如nums=[1, 2, 3, 4, 5, 6, 7], k = 3
,那么元素5, 6, 7
就会被轮转到数组的前端,则v
就需要将5, 6, 7
存储进来,其余元素经过轮转后只是向后挪动了几个位置,这个很好处理。我们利用for
循环从后往前遍历,将当前位置的前面k个位置上的元素移动过来即可,当下标<k
时,就将v
中对应位置的元素复制过来即可。
class Solution {
public:void rotate(vector<int>& nums, int k) {k = k % nums.size(); //剪枝避免多余的轮转vector<int> v;for(int i = nums.size() - k; i < nums.size(); ++i)v.emplace_back(nums[i]);for(int i = nums.size() - 1; i >= 0; --i){if(i >= k) nums[i] = nums[i - k];else nums[i] = v[i];}}
};
看了下灵神的题解,感觉他的思路比较有泛化性,三次反转的思路可以应用在轮转的问题上,主要是看下三次反转为什么可以实现轮转的效果,这里直接看灵神的证明就好了,我觉得还蛮通俗易懂的。
灵神也提到了剪枝的问题,为了避免无效的轮转,我们需要先对k取模再进行反转。
class Solution {
public:void rotate(vector<int>& nums, int k) {k = k % nums.size(); //剪枝避免多余的轮转reverse(nums.begin(), nums.end()); //反转数组中的所有元素reverse(nums.begin(), nums.begin() + k); //反转前k个元素reverse(nums.begin() + k, nums.end()); //反转后n - k个元素}
};