题目
给定一个数组,要求输出所有的排列组合结果
思路一:
- 对于数组a[1, 2, 3]来说,我们在创建一个辅助数组b[ ],
- 第一次:把a中的1移到b中 ——>a[2, 3] b[ 1 ]
然后现在有两种移动方法:先移动2,或者先移动3 形成[1,2,3]或者[1,3,2],这时候a数组就变为空了。然后再把数组返还给a。 - 第二次:把a中的2移到b中 ——>a[1, 3] b[ 2 ]
同理:形成[2,1,3]或者[2,3,1],然后再把数组返还给a。 - 第三次:同上。
如果我们以这样的思路来想,那么其实只要做三个步骤:
1.借出去
2.排序
3.还回来
采用递归的思想,代码如下:
public void WholeArrange(List<Integer> oriList, List<Integer> list){
if(oriList.size() > 0){//如果原数组大于0就继续递归
for(int i=0; i<oriList.size(); i++){
list.add(oriList.remove(i));//“借”,add是尾插。
WholeArrange(oriList,list);
oriList.add(i,list.remove(list.size()-1));//“还”,从i位置借,就还回i位置,
}
}else{
System.out.println(list);
}
}
附上原思路链接 数组全排列详解
缺点:只能逐一输出,不能把所有的输出保存起来,如果需要处理所有的结果集不方便。原因是因为在递归“还”的时候会把辅助数组list中的数删除,无法存储。
思路二:
使用交换的方式,循环每次交换后两个数,通过递归来把i的值变换,相当于循环了三次,每次都从不同的i开始。
- 第一次从1开始:[1,2,3] [1,3,2];
- 第二次从2开始:[2,1,3] [2,3,1];
- 第三次从2开始:[3,2,1] [3,1,2];
终止条件:交换到超过数组下标时,就结束,交换到n-1时,就把值保存
public void WholeArrange(int[] a, start,List<int[]> res) {
if(start = a.length){
return;
}
if(start == a.length -1){
int[] temp = a.clone();
res.add(temp);
return;
}
for(int i=start; i<a.length; i++){
swap(a,start,i);//变换
WholeArrange(a,start+1,res);
swap(a,satrt,i);//还原
}
}
private static void swap(int[] A,int i,int j){
int t = A[i];
A[i] = A[j];
A[j] = t;
}
可以通过res来存储所有的排列,方便后续结果集的处理。