剑指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;
}
}