问题描述:
Given an array, rotate the array to the right by k steps, where k is non-negative.
Example 1:
Input:[1,2,3,4,5,6,7]
and k = 3 Output:[5,6,7,1,2,3,4]
Explanation: rotate 1 steps to the right:[7,1,2,3,4,5,6]
rotate 2 steps to the right:[6,7,1,2,3,4,5]
rotate 3 steps to the right:[5,6,7,1,2,3,4]
Example 2:
Input: [-1,-100,3,99]
and k = 2
Output: [3,99,-1,-100]
Explanation:
rotate 1 steps to the right: [99,-1,-100,3]
rotate 2 steps to the right: [3,99,-1,-100]
Note:
- Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem.
- Could you do it in-place with O(1) extra space?
解题思路:
这是一道easy的题,我一开始也是想着,有现成的方法就用现成的方法吧来去做的,结果就58ms了,12%左右。。
先说一下我的思路吧:
首先为了只做一次有效旋转,我们对k做操作:k = k%nums.size()
以内当k是nums.size()时,其实数组并没有变化。
其次我用了iterator来进行插入,用了vector自带方法进行pop
显然这花费了很久的时间。
代码:
1.我的解法(58ms)
class Solution { public: void rotate(vector<int>& nums, int k) { int nSize = nums.size(); if(nSize <= 1) return; k = k % nSize; for(int i = 0; i < k; i++){ int n = nums.back(); nums.pop_back(); nums.insert(nums.begin(), n); } } };
不妨来看看20ms的做法:
这里对每一个位置的数字求新的位置,并将其放到新的位置上并求这个位置原来数字的新位置,以此循环。
需要注意的是,不能重复替代,该位置被替代一次后就不能够在被替代了,所以用了两个循环。
一开始我不理解为什么是用了两个循环:然后我就把1个循环放到oj去找了下反例:
[1,2,3,4,5,6] k = 2在第一次循环时:
start = 0:
[1,2,3,4,5,6]->[1,2,1,4,3,6]->[5,2,1,4,3,6]
所以此时应从index = 1的位置再找一遍。同时加以限定改变数字次数。
20ms解法:
class Solution { public: void rotate(vector<int>& nums, int k) { k = k % nums.size(); int count = 0; for (int start = 0; count < nums.size(); start++) { int current = start; int prev = nums[start]; do { int next = (current + k) % nums.size(); int temp = nums[next]; nums[next] = prev; prev = temp; current = next; count++; } while (start != current); } } };