你有没有过这种崩溃:让数组[1,2,3,4,5]向右旋转2步,你傻乎乎地拿临时变量一个个挪——先把5存起来,4移到5的位置,3移到4的位置…移到一半记混顺序,最后数组变成[4,5,1,3,2],错得离谱?实则数组旋转根本不用“手动搬砖”,Java里藏着“反转法”的巧劲,像“排队换位置”一样简单,3步就能搞定,再也不用记一堆临时变量!今天用“操场排队”的段子给你讲透,看完笑到会写代码,下次旋转数组你也能当“快手”~
先吐槽“手动挪元素”:像搬砖时把砖砸脚,累还容易错
新手旋转数组,最爱用“暴力搬运法”:列如要把数组[1,2,3,4]向右旋转2步(目标[3,4,1,2]),步骤能绕晕自己:
1. 先把最后2个元素[3,4]存进临时数组;
2. 再把前面2个元素[1,2]往后挪2位,变成[0,0,1,2];
3. 最后把临时数组的[3,4]塞进前面,变成[3,4,1,2]。
这就像操场排队,要让最后2个人站到最前面,你让他们先去旁边等着,前面的人一个个往后退,退完再让这2个人归队——不仅慢,还容易有人站错位置(列如漏挪一个元素,数组就错了)。更坑的是,要是数组有1000个元素,临时数组要开1000个空间,内存像“被快递盒堆满”,纯属给自己找罪受!
反转法的“巧劲”:像排队“集体向后转”,3步搞定旋转

反转法的核心逻辑超简单:**通过三次反转,把“旋转”变成“转身”**,不用临时数组,也不用一个个挪元素。就像操场排队要让最后2人站前面,不用让他们去旁边等,而是:
1. 所有人先集体向后转(全数组反转);
2. 前2个人再向后转(前k个元素反转);
3. 剩下的人最后向后转(后n-k个元素反转);
——三步下来,最后2人自动站到最前面,还不用记顺序!
用数组[1,2,3,4]向右旋转2步举例,一步步看反转法的魔力:
– 原数组:[1,2,3,4](n=4,k=2)
1. 全数组反转:[4,3,2,1](所有人向后转)
2. 前k=2个元素反转:[3,4,2,1](前2人再向后转)
3. 后n-k=2个元素反转:[3,4,1,2](剩下2人再向后转)
——搞定!和目标完全一致,比手动挪快3倍,还没用到临时数组~
Java实现3步反转法:排队类比+代码,新手一看就懂

反转法的Java实现,核心是写一个“反转数组片段”的工具函数,然后调用三次(全反转、前k反转、后n-k反转)。每一步都对应“排队转身”,代码简单到离谱:
第一步:写“反转工具函数”——给指定区间的人“转身”
先写一个`reverse`函数,负责把数组从索引`start`到`end`的元素反转,就像让排队的“第start个到第end个人向后转”:
public class ArrayRotation {
// 反转数组从start到end的元素(左闭右闭区间)
private static void reverse(int[] arr, int start, int end) {
while (start < end) {
// 交换start和end位置的元素(两个人交换位置,相当于转身)
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++; // 向中间挪一步
end--;
}
}
}
列如反转[4,3,2,1]的前2个元素(start=0,end=1):交换4和3,变成[3,4,2,1],就像前2人转身~
第二步:处理旋转次数——避免“绕操场多跑圈”
旋转次数k可能比数组长度n大(列如n=4,k=6),这时候实际旋转步数是`k%n`(6%4=2),由于“绕操场跑6圈和跑2圈一样,多跑的都是白费劲”。如果不处理,会做多余的反转,浪费时间。
代码处理旋转次数:
public static void rotate(int[] arr, int k) {
int n = arr.length;
if (n == 0 || k == 0) return; // 空数组或不旋转,直接返回
k = k % n; // 计算实际旋转步数,避免多余操作
// 后面三步反转写这里...
}
第三步:三次反转——排队转身三连击
调用三次`reverse`函数,对应“全反转→前k反转→后n-k反转”,完成旋转:
public static void rotate(int[] arr, int k) {
int n = arr.length;
if (n == 0 || k == 0) return;
k = k % n;
// 1. 全数组反转(所有人向后转)
reverse(arr, 0, n - 1);
// 2. 反转前k个元素(前k人再向后转)
reverse(arr, 0, k - 1);
// 3. 反转后n-k个元素(剩下的人再向后转)
reverse(arr, k, n - 1);
}
测试一下:旋转[1,2,3,4],k=2
public static void main(String[] args) {
int[] arr = {1,2,3,4};
rotate(arr, 2);
System.out.println(Arrays.toString(arr)); // 输出[3,4,1,2],正确!
}
整个过程没有临时数组,空间复杂度O(1)(省内存像省快递盒),时间复杂度O(n)(只遍历数组3次),比暴力法快10倍,新手也能一次写对~
避坑提醒:新手常踩的2个“旋转陷阱”
1. **旋转次数没取模,导致反转出错**:列如n=4,k=6,没算k%n=2,直接反转前6个元素——数组只有4个元素,索引会越界(报`
ArrayIndexOutOfBoundsException`),就像让排队的前6人转身,结果只有4人,根本转不了。记住:**旋转前先算k = k%n**,避免越界。
2. **反转区间搞反,把“前k”和“后n-k”弄混**:列如该反转前k个(0到k-1),却写成反转0到k,导致多反转一个元素。就像排队该让前2人转身,却让前3人转,最后位置全乱。记准反转区间:**前k个是0到k-1,后n-k个是k到n-1**,左闭右闭!
互动时间:来测测你的“旋转实战力”!
1. 数组[1,2,3,4,5]向右旋转3步(k=3),用反转法的三步操作分别是什么?最终结果是啥?(提示:全反转→[5,4,3,2,1],前3反转→[3,4,5,2,1],后2反转→[3,4,5,1,2])
2. 要是向左旋转2步(列如[1,2,3,4]向左转2步→[3,4,1,2]),反转法该怎么改?(提示:向左旋转k步=向右旋转n-k步)
3. 你第一次旋转数组时,有没有用“手动挪元素”的笨办法?有没有挪错元素导致数组混乱?评论区说说你的“搬砖血泪史”!
评论区交出你的答案,前3名答对的送“Java数组操作手册”(含旋转、去重、排序的通俗讲解+代码模板)!关注我,下期揭秘“如何旋转二维数组(矩阵)”——比一维数组多一步,却能搞定面试高频题,实用到爆~


