题目描述
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
示例
示例 1:
输入: [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]
示例 2:
输入: [-1,-100,3,99] 和 k = 2
输出: [3,99,-1,-100]
解释:
向右旋转 1 步: [99,-1,-100,3]
向右旋转 2 步: [3,99,-1,-100]
答案
解法一:
如果不要求空间复杂度为O(1)的话,可以利用一个辅助数组(把数组的变化看成两部分,左边的部分右移,右边的部分左移)
时间复杂度O(n),空间复杂度O(n)
代码如下:
class Solution {
public void rotate(int[] nums, int k) {
if(nums==null||nums.length<2||(k=k%nums.length)==0){
return;
}
//left存需要往右移的左半部分数组
int[] left = Arrays.copyOfRange(nums,0,nums.length-k);
for(int i=0;i<k;i++){
nums[i] = nums[i+nums.length-k];
}
for(int i=k;i<nums.length;i++){
nums[i] = left[i-k];
}
return;
}
}
解法二
将数组旋转k次,每次旋转1个位置
时间复杂度O(n*k),空间复杂度O(1)
代码如下:
class Solution {
public void rotate(int[] nums, int k) {
if(nums==null||nums.length<2||(k=k%nums.length)==0){
return;
}
while(k>0){
rotateForOne(nums);
k--;
}
}
private void rotateForOne(int[] nums){
int pre = nums[0];
for(int i=1;i<nums.length;i++){
int temp = nums[i];
nums[i] = pre;
pre = temp;
}
nums[0] = pre;
}
}
解法三
直接把元素放到它最后应该在的位置(我们需要把被替换的数字保存在变量 temp 里面。然后,我们将被替换数字temp放到它正确的位置,并继续这个过程 n次)。这有个问题就是可能在没有遍历所有数字的情况下回到出发数字,这就需要加一个判断,如果出现这个情况,就从下一个数字开始,重复上述过程,直到数组中的所有元素都被移动。
时间复杂度O(n),空间复杂度O(1)
代码如下:
class Solution {
public void rotate(int[] nums, int k) {
if(nums==null||nums.length<2||(k=k%nums.length)==0){
return;
}
int count = 0;//移动的次数,当count==nums.length时,移动结束
for(int i=0;count<nums.length;i++){
int current = i;
int pre = nums[i];
do{
current = (current+k)%nums.length;
int temp = nums[current];
nums[current] = pre;
pre = temp;
count++;
}while(current!=i);
}
}
}
解法四
这个解法是三次反转,主要也利用了解法一中提到的特点——(把数组的变化看成两部分,左边的部分右移,右边的部分左移)
算法思路如下图:
时间复杂度O(n),空间复杂度O(1)
代码如下:
class Solution {
public void rotate(int[] nums, int k) {
if(nums==null||nums.length<2||(k=k%nums.length)==0){
return;
}
reverse(nums,0,nums.length-1);
reverse(nums,0,k-1);
reverse(nums,k,nums.length-1);
}
private void reverse(int[] nums,int start,int end){
while(start<end){
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start++;
end--;
}
}
}