leetcode189.轮转数组
题目描述
给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。
题目解法
解法一:暴力旋转
顾名思义,我们根据题目所说每次将数组向右旋转一位,并重复k次。其思路是直接模拟旋转操作:将最后一个元素取出暂存,其余元素依次向右移动一位,再将暂存的原最后一个元素放到数组开头。
class Solution {public void rotate(int[] nums, int k) {int n = nums.length;for (int i = 0; i < k; i++) {int temp = nums[n - 1];for (int j = n - 1; j > 0; j--) {nums[j] = nums[j - 1];}nums[0] = temp;}}
}
该解法的时间复杂度为O(k * n),空间复杂度为O(1)。
解法二:使用额外数组
我们可以直接再定义一个数组,通过计算旋转后每个元素的新位置,直接将元素放进新数组的对应位置。最后将新数组的内容复制回原数组。
class Solution {public void rotate(int[] nums, int k) {int n = nums.length;int[] newNums = new int[n];for (int i = 0; i < n; i++) {newNums[(i + k) % n] = nums[i];}for (int i = 0; i < n; i++) {nums[i] = newNums[i];}}
}
该解法的时间复杂度为O(n),空间复杂度为O(n)。
解法三:数组翻转
使用了三次反转法来实现数组旋转:
- 整体反转:将整个数组反转,这样原数组的最后 k个元素会移动到数组前端,但顺序是逆序的。
- 反转前k个元素:调整前 k个元素的顺序,使其恢复原始顺序。
- 反转剩余元素:调整后 n-k个元素的顺序,使其恢复原始顺序。
需要注意,如果 k
大于数组长度 n
,直接使用 k
进行反转会导致无效操作或错误。例如,当 n = 7
且 k = 10
时,实际有效的旋转步数是 k % n = 3
,因为旋转 n
次后数组会恢复原状。
该方法的时间复杂度为O(n),空间复杂度为O(1)。
class Solution {public void reverse(int[] nums, int start, int end) {while (start < end) {int temp = nums[start];nums[start] = nums[end];nums[end] = temp;start++;end--;}}public void rotate(int[] nums, int k) {int n = nums.length;k %= n;reverse(nums, 0, n - 1);reverse(nums, 0, k - 1);reverse(nums, k, n - 1);}
}