【剑指Offer】38. 字符串的排列
输入一个字符串,打印出该字符串中字符的所有排列。
你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。
示例:
输入:s = “abc”
输出:[“abc”,“acb”,“bac”,“bca”,“cab”,“cba”]
1.递归
class Solution {
public String[] permutation(String s) {
if(s.length()==0)return null;
if(s.length()==1)return new String[]{s.charAt(0)+""};
Set<String> res=new HashSet<>();
for(int i=0;i<s.length();i++){
//将除第i个字符外的其余字符组成新的字符串,递归得到的字符串前再全部加上第i个字符。
String curs=s.substring(0,i)+s.substring(i+1,s.length());
String[] curans=permutation(curs);
if(curans==null)continue;
for(int j=0;j<curans.length;j++){
curans[j]=s.charAt(i)+curans[j];
if(!res.contains(curans[j])){
res.add(curans[j]);
}
}
}
String[] ans=new String[res.size()];
int h=0;
for(String ress:res){
ans[h++]=ress;
}
return ans;
}
}
2. 回溯 (无需set去重)
class Solution {
public String[] permutation(String s) {
int[] nums=new int[259];
for(int i=0;i<s.length();i++){
nums[s.charAt(i)]++;//将重复字符放在同一位置
}
List<String> list=new ArrayList<>();
back(s.length(),"",list,nums);
String[] ans=new String[list.size()];
for(int i=0;i<ans.length;i++){
ans[i]=list.get(i);
}
return ans;
}
public void back(int len,String s,List<String> list,int[] nums){
if(len==s.length()){
list.add(s);
return;
}
for(int i=0;i<nums.length;i++){
if(nums[i]>0){//此方法可以避免加入重复字符串
nums[i]--;
back(len,s+(char)i,list,nums);
nums[i]++;
}
}
}
}