跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

如何使用 StringBuilder 实现字符串全排列(Java 教程)

本文详解如何用 stringbuilder 高效实现字符串全 排列 ,避免字符串拼接开销,并修正递归回溯中常见的状态重置错误,确保输出完整、无重复、无越界异常。 在 Java 中,使用 String 实现全排列虽直观,但因 String 不可变,每次拼接都会创建新对象,时间与空间开销较大。而 StringBuilder 是可变的、线程不安全但高性能的字符序列容器,更适合递归回溯类操作——前提是必须 精准管理其状态:进入递归前修改,返回后彻底还原 。 下面是一个正确、健壮、可直接运行的 StringBuilder 版全排列实现:
public class PermutationWithStringBuilder { public static void permutations(StringBuilder str, StringBuilder ans) { // 递归终止条件:原字符串已选尽 if (str.length() == 0) { System.out.println(ans); return; } // 遍历当前可选的所有字符位置 for (int i = 0; i < str.length(); i++) { char currentChar = str.charAt(i); // ✅ 步骤1:将当前字符加入答案路径 ans.append(currentChar); // ✅ 步骤2:从原字符串中移除该字符(构建剩余待选序列) str.deleteCharAt(i); // ✅ 步骤3:递归处理剩余字符 permutations(str, ans); // ⚠️ 关键:回溯还原!必须严格逆序执行 // 步骤4:从答案中移除最后添加的字符(注意:不是 deleteCharAt(i),而是末尾!) ans.deleteCharAt(ans.length() - 1); // 步骤5:将当前字符插回原位置,恢复 str 状态 str.insert(i, currentChar); } } public static void main(String[] args) { StringBuilder input = new StringBuilder("abc"); StringBuilder answer = new StringBuilder(); permutations(input, answer); } }
输出结果:
abc acb bac bca cab cba
✅ 核心要点解析: Eclipse导入Android或其他的JAVA项目的正确方法 WORD版 本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看 下载 立即学习 “ Java免费学习笔记(深入) ”; ans.append(...) 和 ans.deleteCharAt(ans.length() - 1) 构成一对原子操作:添加 → 递归 → 撤销,确保每层递归的 ans 独立且干净; str.deleteCharAt(i) 后,str 长度减 1,后续索引整体前移;因此回溯时必须用 str.insert(i, ch) 将字符 插回原下标 i (而非 replace 或 append),否则位置错乱导致 StringIndexOutOfBoundsException; ❌ 原代码中 ans.deleteCharAt(i) 是典型错误:i 是原字符串的索引,而 ans 当前长度可能远大于 i,且其末尾字符位置恒为 ans.length()-1; ❌ newstr.replace(i, i, ...) 逻辑错误:replace(start, end, ...) 的 end 是 排他性 索引,replace(i,i,...) 相当于在位置 i 插入,但此时 i 已越界(因 deleteCharAt(i) 后 newstr.length() 减小)。 ? 进阶建议: 若需收集所有排列而非仅打印,可将 System.out.println(ans) 替换为 resultList.add(ans.toString()); 对含重复字符的字符串(如 "aab"),可在循环内增加去重判断:if (i == 0 || str.charAt(i) != str.charAt(i-1))(需先排序); 时间复杂度仍为 O(n×n!),但 StringBuilder 显著降低常数因子,尤其对长字符串更友好。 掌握 StringBuilder 在回溯中的“修改–递归–还原”三步法,是写出高效、无 Bug 递归算法的关键能力。

相关文章