剑指offer--字符串的排列

本文介绍了一种解决字符串全排列问题的递归算法,并通过实例详细解释了递归过程及注意事项,包括如何避免重复排列和使用StringBuilder进行字符串操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

剑指offer–字符串的排列

一、题目描述:
在这里插入图片描述二、思路解析:

全排列的问题,最开始看到这个题目不知道怎么做,看了剑指offer上的方法:
(a)把字符串分成两个部分:第一部分是字符串的第一个字符,第二部分是第一个字符后面的所有字符。之后求第二部分字符的全排列。
(b)拿第一个字符和它后面的字符逐个交换。

看了这个思路之后大致可以理解一下,但是还是不能去实现。之后又在牛客上看了一个小姐姐写的题解:

假设输入为a、b、c
那么其实排序的总数:
fun(a,b,c)=a(fun(b,c))+ a和 b交换 b(fun(a,c))+ a和c交换 c(fun(b,a))
fun(b,c) = b+fun(c)+ b和c 交换 c(fun(b))
fun(c)=1
这样看思路就很清晰了
另外题目中说明可能存在重复的字符,因此在进行交换的时候需要判断进行交换的字符是否相等,如果相等就没有必要交换了

虽然思路清晰,但是这个题目还需要对String和StringBuilder中的方法要熟悉才行。

//String的用法:
//java中String是只读的,没有办法进行变换,因此需要使用StringBuilder。
String.length() //获取字符串的长度
String.charAt(i) //获取第i个字符的内容
String.subString(start)   //获取[start,)的字符串
String.subString(start,end) //获取[start,end)中的字符串
char[] c = iniString.toCharArray() //将字符串转为char数组来进行改变字符内容
String.equal() //判断两个字符串是否相等

//StringBuilder的用法:
除了String中支持的方法外,StringBuilder支持字符的增、删、改。
stringBuilder.append("we");  //添加we在词尾
stringBuilder.insert(0,"we");//在0的位置加入后面的内容
stringBuilder.delete(0,1);  //删除[0,1)的数据
stringBuilder.deleteCharAt(0);
stringBuilder.setCharAt(0,'p'); //在某一个独特位置设置字符
char c = stringBuilder.charAt(i);//查询某个位置上的字符
System.out.println(stringBuilder);
new String(stringBuilder);//用stringBuilder来初始化String

三、代码

import java.util.ArrayList;
import java.util.*;
public class Solution {
    public ArrayList<String> Permutation(String str) {
       StringBuilder strBuilder = new StringBuilder(str);
        ArrayList<String> result = PermutationHelp(strBuilder);
        Collections.sort(result);  //排序操作。
        return result;
    }
    public ArrayList<String> PermutationHelp(StringBuilder str){
        ArrayList<String> result = new ArrayList<String>();
        if(str.length()==1){
            result.add(str.toString());
        }else{
            for(int i=0;i<str.length();i++){
                if(i==0 || str.charAt(i)!=str.charAt(0)){    //第二个条件可以防止重复的发生
                    char temp = str.charAt(i);  //取出第i个字符 ,可以写一个函数完成交换。
                    str.setCharAt(i, str.charAt(0)); //第i个位置插入第0个字符
                    str.setCharAt(0,temp);  //第0个位置插入第i个字符,完成字符的交换
                    ArrayList<String> newResult = PermutationHelp(new StringBuilder(str.substring(1)));
                    for(int j=0; j<newResult.size();j++){
                        result.add(str.substring(0,1)+newResult.get(j));
                    }
                    //将之前交换的字符放回原处
                    temp = str.charAt(0);
                    str.setCharAt(0,str.charAt(i));
                    str.setCharAt(i,temp);
                }
            }
            
        }
        return result;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谁偷了我的月亮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值