题目描述:输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
解题思路:递归+回溯
将要排序的字符串分成两个部分,第一部分是固定的首位字符,第二部分是剩下的字符串(这部分可以递归求解)。首先求出可能在首位的字符串,即把首位字符与后面的字符依次进行交换;而后固定首位字符,递归求解其后字符串的排序。在求解完一个字符排序可能后,要还原为原来是顺序(回溯过程)
Java代码:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.TreeSet;
public class Solution {
public ArrayList<String> Permutation(String str) {
//递归思路
ArrayList<String> res=new ArrayList<String>();
TreeSet<String> Tset = new TreeSet<>();
if(str==null) return res;
char[] ch=str.toCharArray();
Arrays.sort(ch);
perum(ch,Tset,0);
res.addAll(Tset);
return res;
}
public void perum(char[] in,TreeSet<String> list,int start){
if(in==null || in.length==0 || start<0 || start>in.length-1) { return ; }
if(start==in.length-1){
list.add(new String(in));
}else{
for(int i=start;i<in.length;i++){
Move(in,start,i);
perum(in,list,start+1);
Move(in,start,i); //回溯过程,很重要,容易遗忘
}
}
}
public void Move(char[] in,int s,int e){
char tmp=in[s];
in[s]=in[e];
in[e]=tmp;
}
}
Python代码:
class Solution:
def Permutation(self, ss):
# write code here
res = set()
def solve(str, start):
if start == len(str):
res.add(''.join(str))
return
for i in range(start, len(str)):
str[i], str[start] = str[start], str[i]
solve(str, start + 1)
str[i], str[start] = str[start], str[i]
if ss:
solve(list(ss), 0)
return sorted(list(res))
拓展:给定一个可能包含重复项、nums的整数集合,返回所有可能的子集(幂集)。(组合问题)
思路:
class Solution:
def subsetsWithDup(self, S):
res = [[]]
S.sort()
for i in range(len(S)):
if i == 0 or S[i] != S[i - 1]:
l = len(res)
for j in range(len(res) - l, len(res)):
res.append(res[j] + [S[i]])
return res