题目:189. 轮换数组
链接:link
解题方法
方法一:使用额外的数组
通过创建一个新的数组,并按照旋转规则将原数组的元素放入新数组中的正确位置。
方法二:环状替换
思路
核心思想是通过计算每个元素旋转后的位置,并进行替换,同时记录已替换的元素位置,避免重复替换。这种方法避免了使用额外的数组空间,直接在原数组上进行操作。
-
初始化变量
k k k:旋转的步数,需要取模 n u m s . l e n g t h nums.length nums.length,以确保k的值在数组长度的范围内。
c o u n t count count:记录已经替换过的元素个数,初始化为0。
s t a r t start start:遍历数组的起始位置,用于控制循环的开始。 -
遍历数组
使用一个外层循环来遍历数组,直到 c o u n t count count等于数组的长度,即所有元素都被替换过。
在每次循环的开始,如果 s t a r t start start是数组长度的整数倍(即回到了最初的起始点),则将 c o u n t count count加1,表示开始新的一轮替换。 -
计算并替换元素
对于每个起始位置 s t a r t start start,计算它旋转 k k k步后的位置 n e x t next next。
使用一个内层循环来不断替换元素,直到元素回到了起始位置 s t a r t start start,形成一个环形替换。
在内层循环中,不断交换 n u m s [ c u r r e n t ] nums[current] nums[current]和 n u m s [ n e x t ] nums[next] nums[next]的值,并更新 c u r r e n t current current和 n e x t next next的位置,直到回到起始位置。 -
结束条件
当 c o u n t count count等于数组的长度时,说明所有元素都已经按照要求被替换过,算法结束。 -
时间复杂度: O ( n ) O(n) O(n),空间复杂度: O ( 1 ) O(1) O(1)。
代码
class Solution {
public void rotate(int[] nums, int k) {
if (nums == null || nums.length == 0 || k <= 0) {
return;
}
int n = nums.length;
k = k % n; // 处理k大于数组长度的情况
int count = 0;
for (int start = 0; count < n; start++) {
int current = start;
int prev = nums[start];
do {
int next = (current + k) % n;
int temp = nums[next];
nums[next] = prev;
prev = temp;
current = next;
count++;
} while (start != current);
}
}
}