一.递归法
问题:
全排列问题及给出一个序列如{a,b,c}输出它的全排列,一共有3!=6种排法.及一个n个元素的序列全排列有n!个排列方法.那么如何得到每种排列呢?
解析:
首先拿到一个题目先用数学的思想去考虑怎么解决.我们在纸上模拟这道题目的过程,其实就是我们算法实现的过程,只不过需要我们通过程序代码使其形成一种闭环的操作,让它自己迭代得到最终的结果.全排列问题是递归的一种典型问题.举个例子{1,2,3}的去全排列.首先我们会定第一个元素1不动,交换2,3的位置形成两种全排列,然后再让第一元素1与其他位置交换,重复上面的操作,由此得到整个序列的全排列.为什么会这样做呢?原因是其实上述步骤我们直接省略了一部,及在定下第一个元素后,我们再定下第二个元素,第三个元素则确定下来,因为单个元素的全排列是它自身,所以这个时候我们没有其他的排列方式了,就回到第二个元素,更换第二个元素{2,3},将第二个元素换成3,这时和上述情况一样,得到一种排序.我们在回想一下上述过程有有限推到无限.n个元素的全排列其实就是n*(n-1个元素的全排列),(这里的n的意思是,n次更换第一个元素)即
p = {a1,a2,a3,a4….an},perm(p)为p的全排列则perm(p) = a1perm(p-a1)+a2perm(p-a2)…..+anperm(p-an);由此可以得出最终算法实现如下
import java.util.*;
public class Solution {
ArrayList<String> list = new ArrayList<String>();
public ArrayList<String> Permutation(String str) {
if(str.equals(""))
return list;
char[] s = str.toCharArray();
sort(s,0,s.length-1);
Collections.sort(list);
return list;
}
public void sort(char[] s,int first,int end){
if(first >= end){
list.add(String.valueOf(s));
}else{
for(int i = first ; i <= end ;i++ ){
if(i == first || s[i] != s[first]){
swap(s,first,i);
sort(s,first+1,end);
swap(s,first,i);
}
}
}
}
public void swap(char[] s,int i,int j){
char temp = s[i];
s[i] = s[j];
s[j] = temp;
}
}
}
上面代码是剑指Offer的字符串排序题目的ac代码.里面还有一个问题没有解决就是当输入字符串是abb的时候第二元素和第三个元素交换会形成重复问题,所以在这里说一下优化,就是设置一个HashSet,可以自动判断每次交换的是否重复
二.字典序生成法
解析:
依然是全排列问题,下面用字典生成法来解,懵逼,一个大写的懵逼.未完待续,明天补上