
本文详解如何通过双层反转法(先逐词反转,再整体反转)实现用户输入字符串的单词级逆序,并重点剖析原代码中因边界处理不当导致的空格错位问题及修复方法。
本文详解如何通过双层反转法(先逐词反转,再整体反转)实现用户输入字符串的单词级逆序,并重点剖析原代码中因边界处理不当导致的空格错位问题及修复方法。
在 Java 中实现“单词级反转”(如将 "I like ice cream!" 变为 "cream! ice like I"),关键在于区分字符反转与单词反转逻辑。常见误区是直接对整个字符串调用 StringBuilder.reverse()——这会得到字符级逆序 "!maerc eci ekil I",而非目标结果。正确做法是采用经典的 “两次反转”策略:
- 先对每个单词内部字符进行反转(如 "like" → "ekil");
- 再对整个字符数组整体反转("ekil eci ekil !maerc" → "cream! ice like I")。
但原代码存在一个隐蔽却致命的边界错误:reverseWords 方法中,当检测到空格 s[end] == ' ' 时,直接调用 reverse(s, start, end),将空格本身也纳入了单次反转范围。例如字符串 "I like"(索引 0='I', 1=' ', 2='l'…),当 end=1 时触发 reverse(s, 0, 1),导致 'I' 和 ' ' 互换,结果首字符变成空格,后续逻辑全部错乱。
✅ 正确修复方式是:在遇到空格时,仅反转 start 到 end-1(即空格前最后一个有效字符)。修改后的核心逻辑如下:
static char[] reverseWords(char[] s) {
int start = 0;
for (int end = 0; end < s.length; end++) {
if (s[end] == ' ') {
reverse(s, start, end - 1); // ✅ 关键修复:end-1,排除空格
start = end + 1;
}
}
reverse(s, start, s.length - 1); // 反转最后一个单词(无后续空格)
reverse(s, 0, s.length - 1); // 反转整个数组,完成单词顺序翻转
return s;
}同时,reverse 辅助方法需确保区间闭合正确(start <= end),其内部交换逻辑无误,仅负责指定索引范围内字符的原地翻转。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
立即学习“Java免费学习笔记(深入)”;
⚠️ 注意事项:
- 所有 reverse 调用均作用于同一份 char[] 引用,因此修改是可见的;但各方法内的局部变量(如 start、end)完全独立,不会相互干扰;
- 若输入末尾无空格(如 "hello world"),循环结束后必须额外调用一次 reverse(s, start, s.length-1) 处理最后一个单词;
- 该算法时间复杂度为 O(n),空间复杂度为 O(1)(不计输入转换开销),高效且无需额外字符串拼接。
运行修复后代码,输入 "I like ice cream!" 将精准输出 "cream! ice like I",真正实现单词粒度的语义逆序。

















