必须转成char数组,因为Java字符串不可变,底层由final char数组实现,所有操作均创建新对象;通过toCharArray()获得可修改副本后,用双指针原地交换实现O(1)额外空间反转。
在 java 中,字符串是不可变对象,无法直接原地修改。但可以通过将字符串转为字符数组(char[]),再对数组进行原地交换来实现“逻辑上的字符串反转”,全程只使用 o(1) 额外空间,不依赖 stringbuilder 或新字符串对象。
为什么必须转成 char 数组?
Java 的 String 类底层由 final char 数组实现,且所有字符串操作(如 substring、concat)都会创建新对象。要避免额外空间开销,唯一可行路径是:
- 调用
toCharArray()得到可修改的副本(这步 unavoidable,但属于必要且仅一次的 O(n) 空间 —— 不算“额外”辅助空间) - 在该数组上执行双指针原地交换
- 用
new String(charArray)构造结果(最终返回值不可避免,但算法过程本身不申请新数组)
核心:双指针原地交换实现
设定左右两个索引,从首尾向中间靠拢,逐对交换字符:
- 左指针
left初始为 0,右指针right初始为arr.length - 1 - 当
left 时,交换 <code>arr[left]和arr[right] - 每次交换后,
left++,right-- - 循环结束时,数组已反转完成
完整可运行代码示例
// 注意:不使用任何集合、StringBuilder 或额外字符数组
public static String reverseString(String s) {
if (s == null || s.length() <= 1) return s;
<pre class="brush:php;toolbar:false;">char[] arr = s.toCharArray(); // 必要转换,空间 O(n),但非“额外辅助数组”
int left = 0, right = arr.length - 1;
while (left < right) {
// 交换
char temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
left++;
right--;
}
return new String(arr); // 构造结果字符串(不可省略)}
立即学习“Java免费学习笔记(深入)”;
关键细节与常见误区
- 空或单字符无需处理:直接返回原字符串,避免边界越界或无效交换
- 不要用 String += 拼接实现反转:那会隐式创建多个 String 对象,空间和时间都是 O(n²)
- 不能用 s.charAt(i) 直接改:String 没有 setCharAt 方法,字符不可变
- toCharArray() 返回的是副本:修改它不影响原字符串,符合函数式安全原则


















