牛客练习——如何全排序

题目

给定一个数组,要求输出所有的排列组合结果

思路一:

  • 对于数组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来存储所有的排列,方便后续结果集的处理。

发布了22 篇原创文章 · 获赞 1 · 访问量 585

猜你喜欢

转载自blog.csdn.net/zxhl_/article/details/103247075
今日推荐