双指针反转数组时for循环边界应设为i
Java里用双指针反转数组,
for循环边界怎么设才不越界双指针反转本质是交换
arr[i]和arr[j],关键在循环条件:必须让i 成立,否则会重复交换甚至越界。常见错误是写成 <code>i 或 <code>i ,导致中间元素被换两次、或访问 <code>arr[arr.length]报ArrayIndexOutOfBoundsException。
- 正确写法:
for (int i = 0, j = arr.length - 1; i- 当数组长度为奇数(如5),循环在
i=2, j=2前停止,中间元素不动,符合预期- 当长度为偶数(如4),最后一次交换是
i=1, j=2,之后i变成2、j变成1,i 不再成立,自然退出原地反转 vs 创建新数组:为什么别轻易用
Arrays.copyOf有人习惯先复制数组再反转,以为“更安全”,但实际多分配内存、触发GC,且掩盖了对原数组修改意图不明确的问题。除非业务明确要求保留原数组,否则原地反转更直接、也更符合多数场景(比如排序前预处理、字符串转字符数组后清洗)。
- 原地反转:只用
O(1)额外空间,时间O(n/2)- 复制+反转:额外
O(n)空间,且如果后续忘了用新数组,可能还在操作旧引用- 若真需副本,显式写
char[] copy = Arrays.copyOf(arr, arr.length),比隐式复制更可控
int[]和String反转不能套同一套逻辑
String是不可变对象,没有“原地反转”这回事;而int[]是可变引用,可以直接改内容。想反转字符串,必须先转成char[],反转完再用new String(charArr)构造新串。
Java Maven Common下载Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 错例:
str.charAt(0) = str.charAt(str.length()-1)—— 编译报错,charAt是 getter,没 setter- 对例:
char[] cs = str.toCharArray(); reverseInPlace(cs); return new String(cs);- 注意
toCharArray()返回的是新数组,不影响原String,这点和ArrayList.toArray()类似泛型数组无法直接用双指针反转?
T[]的坑在哪Java 泛型擦除后,
T[]无法像int[]那样直接 new 出运行时类型数组,所以通用反转方法要么限定为Object[],要么靠反射或用户传入Class<t></t>。日常开发中,90% 的情况其实不需要泛型版本——用Collection接口的Collections.reverse()更稳妥。
- 对
List<string></string>:直接Collections.reverse(list),内部也是双指针,但封装好了- 对原始类型数组(
int[],double[]):只能手写,因为Arrays工具类没提供原生反转方法- 自己写泛型方法时,别写
public static <t> void reverse(T[] arr)</t>—— 运行时会因类型擦除导致ClassCastException双指针看着简单,但边界、可变性、类型擦除这三个地方一不留神就掉坑里。尤其当数组来自外部输入或嵌套在复杂对象里时,先确认它是可变的、长度非零、索引合法,比急着写交换逻辑更重要。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南












