1.题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
2.算法描述
回溯的思想,用递归实现。所有的字符都可以放在第1个位置,在选择某个字符放在第1个位置之后,剩下的字符的全排列又可以看作是一个同样的问题。
1)初始遍历第idx(idx初始为1)个位置的所有可能,即将第i个字符与后面的所有字符交换位置。
2)固定第idx个位置的,求从idx+1开始的子序列的全排列(即递归idx+1)。
3.代码描述
3.1.Java代码
import java.util.*;
public class Solution {
public ArrayList<String> Permutation(String str) {
ArrayList<String> ans = new ArrayList<>();
if(str == null || str.length() == 0)//如果字符串为空则直接返回
return ans;
helper(ans, 0, str.toCharArray());//从第1个位置开始递归
Collections.sort(ans);//按字典序排序
return ans;
}
private void helper(ArrayList<String> list, int idx, char[] arr){
if(idx == arr.length-1){//如果idx到了最后一个字符了 说明找到一个排列
String s = String.valueOf(arr);
if(!list.contains(s))//如果这个排列不在答案列表中
list.add(s);
}
else{
for(int i=idx; i<arr.length; i++){//将第i个位置字符和后续所有字符进行交换
swap(arr, idx, i);//交换第idx个位置和第i个位置的字符
helper(list, idx+1, arr);//固定了第idx个位置,递归地寻找子序列的全排列
swap(arr, idx, i);//交换回来 以便将第idx个位置字符和后续另一个字符进行交换
}
}
}
private void swap(char[] arr, int i, int j){
char temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
3.2.Python代码
# -*- coding:utf-8 -*-
class Solution:
def Permutation(self, ss):
# write code here
ans = []
if not ss:
return ans
self.helper(ans, 0, list(ss))
ans.sort()
return ans
def helper(self, lst, idx, chars):
if idx == len(chars)-1:
if ''.join(chars) not in lst:
lst.append(''.join(chars))
else:
for i in range(idx, len(chars)):
chars[i], chars[idx] = chars[idx], chars[i]
self.helper(lst, idx+1, chars)
chars[i], chars[idx] = chars[idx], chars[i]