0

0

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

霞舞

霞舞

发布时间:2026-01-11 12:39:09

|

110人浏览过

|

来源于php中文网

原创

如何使用 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

核心要点解析:

DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

下载

立即学习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 递归算法的关键能力。

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

831

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

737

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

733

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

397

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

398

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

446

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

430

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16925

2023.08.03

c++主流开发框架汇总
c++主流开发框架汇总

本专题整合了c++开发框架推荐,阅读专题下面的文章了解更多详细内容。

80

2026.01.09

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2.4万人学习

C# 教程
C# 教程

共94课时 | 6.5万人学习

Java 教程
Java 教程

共578课时 | 44.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号