给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
进阶:
尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
你可以使用空间复杂度为 O(1) 的 原地 算法解决这个问题吗?
第一个办法:创建一个新数组,然后再将原有数组copy。
class Solution{
public void romote(int [ ] arr , int k)
{
int n=arr.length;
int [ ] a=new int[n];
for(int i=0;i<n;i++)
{
a[(i+k)%n)=arr[i];
}
System.arraycopy(a,0,arr,0,n);
}
}
其中System.arraycopy的用法如下,下面是 System.arrayCopy的源代码声明 :
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
代码解释:
Object src : 原数组
int srcPos : 从元数据的起始位置开始
Object dest : 目标数组
int destPos : 目标数组的开始起始位置
int length : 要copy的数组的长度
根据题意,如果使用多余数组存储空间,会导致空间复杂度为 nn,所以在这里,我们可以使用常量级的空间复杂度解法:数组翻转。
思路如下:
首先对整个数组实行翻转,这样子原数组中需要翻转的子数组,就会跑到数组最前面。
这时候,从 kk 处分隔数组,左右两数组,各自进行翻转即可。
class Solution {
public void rotate(int[] nums, int k) {
k %= nums.length;
reverse(nums, 0, nums.length - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, nums.length - 1);
}
public void reverse(int[] nums, int start, int end) {
while (start < end) {
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start += 1;
end -= 1;
}
}
}