题目:输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba
字符可能重复。
这道题的思想是:总的全排列为,第一个字符与自己交换,固定第一个字符然后再求后面的全排列,第一个字符与第二个字符交换然后固定第一个求后面的全排列,。。。以此类推,可以得出递归程序:
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
public class Solution {
public ArrayList<String> Permutation(String str) {
ArrayList<String> list=new ArrayList<String>();
Set<String> set=new TreeSet<String>();
if(str==null)return list;
if(str.equals(""))return list;
permutation(str.toCharArray(),0,set);
for(String s:set)
list.add(s);
return list;
}
public static void permutation(char[] chars,int begin,Set<String> set){
if(begin==chars.length){
set.add(new String(chars));
}else{
for(int i=begin;i<chars.length;++i){
char temp=chars[begin];
chars[begin]=chars[i];
chars[i]=temp;
permutation(chars,begin+1,set);
temp=chars[i];
chars[i]=chars[begin];
chars[begin]=temp;
}
}
}
}
还有一种思想是:通过求下一个排列,来求出全部排列
在当前序列中,从尾端往前寻找两个相邻元素,前一个记为first,后一个记为second,并且满足first 小于 second。然后再从尾端寻找另一个元素number,如果满足first 小于number,即将第first个元素与number元素对调,并将second元素之后(包括second)的所有元素颠倒排序,即求出下一个序列
example:
6,3,4,9,8,7,1
此时 first = 4,second = 9
从尾巴到前找到第一个大于first的数字,就是7
交换4和7,即上面的swap函数,此时序列变成6,3,7,9,8,4,1
再将second=9以及以后的序列重新排序,让其从小到大排序,使得整体最小,即reverse一下(因为此时肯定是递减序列)
得到最终的结果:6,3,7,1,4,8,9
public void nextPermutation(int[] nums) {
// find two adjacent elements, n[i-1] < n[i]
int i = nums.length - 1;
for (; i > 0; i --) {
if (nums[i] > nums[i-1]) {
break;
}
}
if (i != 0) {
// swap (i-1, x), where x is index of the smallest number in [i, n)
int x = nums.length - 1;
for (; x >= i; x --) {
if (nums[x] > nums[i-1]) {
break;
}
}
swap(nums, i - 1, x);
}
reverse(nums, i, nums.length - 1);
}
void swap(int[] a, int i, int j) {
int t = a[i];
a[i] = a[j];
a[j] = t;
}
// reverse a[i, j]
void reverse(int[] a, int i, int j) {
for (; i < j; i ++, j --) {
swap(a, i, j);
}
}
此外还有一种思想是:对于数字序列1,2,3,4 的全排列形成过程是遍历1的时候 全排列为1,遍历到2的时候,将2插入到0,,1的位置,,形成21,21,遍历3的时候,将3依次插入到0,,2的位置321,231,213,同理将4插入到0,,,3的位置。这需要借助一种数据结构队列。
具体代码:
private static List<List<Integer>> getPermutation(int[] a) {
LinkedList<List<Integer>> res=new LinkedList<>();
res.add(new ArrayList<Integer>());
for(int num:a){
int size=res.size();
for(;size>0;size--){
List<Integer> r=res.pollFirst();
for(int i=0;i<=r.size();i++){
List<Integer> temp=new ArrayList<Integer>(r);
temp.add(i,num);
res.add(temp);
}
}
}
return res;
}