一、题目描述
给定一个整数数组 nums
,将数组中的元素向右轮转 k
个位置,其中 k
是非负数。
示例 1:
输入: nums = [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:
输入:nums = [-1,-100,3,99], k = 2 输出:[3,99,-1,-100] 解释: 向右轮转 1 步: [99,-1,-100,3] 向右轮转 2 步: [3,99,-1,-100]
提示:
1 <= nums.length <= 10^5
-2^31 <= nums[i] <= 2^31 - 1
0 <= k <= 10^5
二、解题思路
-
首先处理k值大于数组长度的情况,因为旋转k次后,可能会回到原数组。我们可以使用k = k % nums.length来处理这种情况。
-
使用额外的数组来保存旋转后的数组。
-
将原数组从位置nums.length - k到nums.length - 1的元素复制到新数组的开始位置。
-
将原数组从位置0到nums.length - k - 1的元素复制到新数组的剩余位置。
-
将新数组的元素复制回原数组。
三、具体代码
class Solution {
public void rotate(int[] nums, int k) {
// 处理k值大于数组长度的情况
k = k % nums.length;
// 创建一个新数组来保存旋转后的结果
int[] rotated = new int[nums.length];
// 将原数组从位置nums.length - k到nums.length - 1的元素复制到新数组的开始位置
System.arraycopy(nums, nums.length - k, rotated, 0, k);
// 将原数组从位置0到nums.length - k - 1的元素复制到新数组的剩余位置
System.arraycopy(nums, 0, rotated, k, nums.length - k);
// 将新数组的元素复制回原数组
System.arraycopy(rotated, 0, nums, 0, nums.length);
}
}
四、时间复杂度和空间复杂度
1. 时间复杂度
k = k % nums.length;
这行代码的时间复杂度是O(1),因为取余操作是常数时间操作。System.arraycopy(nums, nums.length - k, rotated, 0, k);
这行代码的时间复杂度是O(k),因为它复制了k个元素。System.arraycopy(nums, 0, rotated, k, nums.length - k);
这行代码的时间复杂度是O(n-k),因为它复制了n-k个元素。System.arraycopy(rotated, 0, nums, 0, nums.length);
这行代码的时间复杂度是O(n),因为它复制了整个数组。
综合以上步骤,总的时间复杂度是O(1) + O(k) + O(n-k) + O(n)。由于k和n-k都是小于或等于n的,所以可以简化为O(n),即线性时间复杂度。
2. 空间复杂度
int[] rotated = new int[nums.length];
这行代码声明了一个与原数组大小相同的新数组,因此空间复杂度是O(n)。
五、总结知识点
-
取余操作 (
k = k % nums.length;
):用于处理当旋转次数k大于数组长度的情况。通过取余操作,可以确保旋转次数在数组的实际长度范围内。 -
数组复制 (
System.arraycopy(...)
):System.arraycopy
是Java中的一个方法,用于在数组之间复制元素。它是一个高效的方法,通常比循环复制要快,因为它是由底层系统直接实现的。 -
数组的创建 (
int[] rotated = new int[nums.length];
):创建一个与原数组大小相同的新数组,用于存储旋转后的元素。 -
数组索引:代码中使用了数组索引来访问和复制数组元素,如
nums.length - k
和nums.length - 1
,这涉及到数组的基本索引操作。 -
方法重载:
System.arraycopy
方法被重载了,以支持不同的参数列表。这里使用了三个重载版本,分别用于复制不同范围的数组元素。 -
参数传递:代码中的
System.arraycopy
方法调用展示了如何传递数组、起始索引、目标数组、目标起始索引和要复制的元素数量作为参数。 -
边界条件处理:在复制数组元素时,考虑了边界条件,确保不会超出数组的索引范围。
以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。