排列

/**
 * input a string(char[]), output all the sequence.
 * {a,b,c,d,e}, output ....
 * 
 * 扩展:
 * a 有重复元素的全排列
 * b 两个数字元素不能连续排列
 * c 某一位不能为给定值
 * 
 * @author root
 *
 */
public class AllSequence {
	
	public static int count;

	public static void list(char[] c, int begin, int end){
		assert(true);
		if(begin == end){
			Tools.printArray(c);
			count++;
			return;
		}
		for(int i=begin; i<=end; i++){
			Tools.swap(c, begin, i);
			list(c, begin+1, end);
			Tools.swap(c, begin, i);
		}
	}
	
	public static ArrayList<int[]> getAllSequence(int[] a){
		ArrayList<int[]> list = new ArrayList<int[]>();
		list(a, 0, a.length-1, list);
		return list;
	}
	
	private static void list(int[] a, int begin, int end, ArrayList<int[]> list){
		assert(true);
		if(begin == end){
			int[] b = Tools.copyArray(a);
			list.add(b);
			return;
		}
		for(int i=begin; i<=end; i++){
			Tools.swap(a, begin, i);
			list(a, begin+1, end, list);
			Tools.swap(a, begin, i);
		}
	}
	
	public static void list2(int[] a, int begin, int end){

		if(begin == end){
//			if(a[end]==1 && a[end-1]==3){//b2
//				return;
//			}
//			if(a[1] == 2){//c 第二位不能是2
				Tools.printArray(a);
				count++;
//			}
			return;
		}
		for(int i=begin; i<=end; i++){
			// a 过滤重复数字,原理就是同一递归层次中,已经出现过的数字不用与首元素交换,从第一个开始。
			//可以进一步减少时间复杂度,先保证输入数组有序,然后下一个元素只和当前首元素比较
			if(i>begin && isExist(a, begin, i)){
				continue;
			}
			//b1 3后面不能是1
//			if(begin>0){
//				if((a[begin-1]==3 && a[i]==1)){
//					continue;
//				}
//			}

			Tools.swap(a, begin, i);
			list2(a, begin+1, end);
			Tools.swap(a, begin, i);
		}
	}
	
	/**
	 * 本方法复杂度有改进,但是要求数组有序
	 * @param a
	 * @param begin
	 * @param end
	 */
	public static void list3(int[] a, int begin, int end){

		if(begin == end){
			Tools.printArray(a);
			count++;
			return;
		}
		int head = a[begin]-1;//保证当前head元素值不等于a[begin]
		for(int i=begin; i<=end; i++){
			// a 过滤重复数字, 必须保证输入数组有序。
			if(head == a[i]){
				continue;
			}else{
				head = a[i];
			}

			Tools.swap(a, begin, i);
			list2(a, begin+1, end);
			Tools.swap(a, begin, i);
		}
	}
	private static boolean isExist(int[] a, int begin, int current){
		for(int i=begin; i<current; i++){
			if(a[i] == a[current]){
				return true;
			}
		}
		return false;
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
//		char[] c = {'a', 'b', 'c', 'd', 'e'};
//		AllSequence.list(c, 0, c.length-1);
//		System.out.println(AllSequence.count);
		
		int[] a = {1,2,2,3};
		AllSequence.list3(a, 0, a.length-1);
		System.out.println(AllSequence.count);
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值