题目:189.轮转数组
- 示例 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
思路1
我们可以使用额外的数组来将每个元素放至正确的位置。遍历原数组,将原数组下标为i的元素放至新数组下标为(i + k) % nums.length的位置,最后将新数组拷贝至原数组即可。
- 时间复杂度:O(n)
- 空间复杂度:O(n)
代码
public void rotate(int[] nums, int k) {
int[] newNums = new int[nums.length];
// 处理 k 大于 n 的情况
k = k % nums.length;
for (int i = 0; i < nums.length; i++) {
newNums[(i + k) % nums.length] = nums[i];
}
System.arraycopy(newNums, 0, nums, 0, nums.length);
}
思路2
- 首先将整个数组翻转。
- 然后翻转前
k个元素。 - 最后翻转剩余的元素。
nums = "----->-->"; k =3
result = "-->----->";
翻转 "----->-->" 可以得到 "<--<-----"
翻转 "<--" 可以得到 "--><-----"
翻转 "<-----" 可以得到 "-->----->"
- 时间复杂度:O(n)
- 空间复杂度:O(1)
代码
public void rotate(int[] nums, int k) {
// 处理 k 大于 n 的情况
k = k % nums.length;
// 反转整个数组
reverse(nums, 0, nums.length - 1);
// 反转前 k 个元素
reverse(nums, 0, k - 1);
// 反转前 k 个元素
reverse(nums, k, nums.length - 1);
}
private void reverse(int[] nums, int begin, int end) {
while (begin < end) {
int temp = nums[begin];
nums[begin] = nums[end];
nums[end] = temp;
begin++;
end--;
}
}