面试经典 150 题 ---- 轮转数组
- 轮转数组
- 方法一:使用额外的数组
- 方法二:数组翻转
轮转数组
方法一:使用额外的数组
我们可以使用额外的数组来将每个元素放至正确的位置。用 n 表示数组的长度,我们遍历原数组,将原数组下标为 i
的元素放至新数组下标为 (i+k) mod n
的位置,最后将新数组拷贝至原数组即可。
class Solution {
public void rotate(int[] nums, int k) {
int len = nums.length;
int[] newArr = Arrays.copyOf(nums, len);
for (int i = 0; i < len; i ++ ) {
nums[(i + k) % len] = newArr[i];
}
}
}
时间复杂度: O(n)
空间复杂度: O(n)
java 中拷贝数组的方法:
- System.arraycopy() 方法:
System.arraycopy(源数组, 源数组起始位置, 目标数组, 目标数组起始位置, 拷贝长度);
int[] sourceArray = {1, 2, 3, 4, 5};
int[] destinationArray = new int[5];
System.arraycopy(sourceArray, 0, destinationArray, 0, sourceArray.length);
- Arrays.copyOf() 方法:
int[] newArray = Arrays.copyOf(源数组, 新数组长度);
int[] sourceArray = {1, 2, 3, 4, 5};
int[] newArray = Arrays.copyOf(sourceArray, sourceArray.length);
- Arrays.copyOfRange() 方法:
int[] newArray = Arrays.copyOfRange(源数组, 起始位置, 结束位置);
int[] sourceArray = {1, 2, 3, 4, 5};
int[] newArray = Arrays.copyOfRange(sourceArray, 0, sourceArray.length);
- 使用clone() 方法:
int[] newArray = sourceArray.clone();
int[] sourceArray = {1, 2, 3, 4, 5};
int[] newArray = sourceArray.clone();
方法二:数组翻转
我们将数组向右移动 k 个位置,那么数组尾部的 k % n 个元素就会移动到数组的头部,同样数组中其它元素就会向后移动 k % n 个位置。
我可以将整个数组进行一次翻转,这样尾部的 k % n 个数组就会移动到头部,然后再分别翻转 [0, k % n - 1] 部分的数组和 [k % n, n - 1] 部分的数组就可以得到答案。
class Solution {
public void rotate(int[] nums, int k) {
int len = nums.length;
reverse(nums, 0, len - 1);
reverse(nums, 0, k % len - 1);
reverse(nums, k % len, len - 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;
}
}
}
时间复杂度: O(n)
其中 n 为数组的长度。每个元素被翻转两次,一共 n 个元素,因此总时间复杂度为 O(2n)=O(n)
空间复杂度: O(1)