【Java蓝桥杯 全排列模板使用】

  • 全排列模板-数组 2013年 第四届 蓝桥杯【带分数】
  • 全排列模板-字符数组 2014年 第五届 蓝桥杯【扑克排序】
  • 全排列模板-无重复元素 2016年 第七届 蓝桥杯【凑算式】

1.全排列 交换回溯法

无字典排序

	public static void main(String[] args) {
		int a[]= {1,2,3};
		f(a,0);
	}

	private static void f(int[] a, int k) {
		if (k==a.length) {
			for (int x:a) {
				System.out.print(x);
			}
			System.out.println();
		}else {
			for (int i = k; i < a.length; i++) {
				int t=a[i];
				a[i]=a[k];
				a[k]=t;
				f(a, k+1);
				t=a[i];
				a[i]=a[k];
				a[k]=t;
			}
		}
		
	}

2.全排列 前缀法

有字典排序

	public static void main(String[] args) {
		String string = "123";
		f("", string.toCharArray());

	}
	private static void f(String k, char[] arr) {
		if (k.length() == arr.length) {
			System.out.println(k);
		}
		for (int i = 0; i < arr.length; i++) {
			char ch = arr[i];
			// 理解点:这个字符可用:在k中出现的次数<在字符集出现的次数
			if (counts(k, ch) < counts(arr, ch)) {
				f(k + ch, arr);
			}
		}
	}

	static int counts(char[] arr, char ch) {
		int sum = 0;
		for (char c : arr) {
			if (c == ch) {
				sum++;
			}
		}
		return sum;
	}

	static int counts(String s, char ch) {
		int sum = 0;
		for (int i = 0; i < s.length(); i++) {
			if (s.charAt(i) == ch)
				sum++;
		}
		return sum;
	}

3.啊哈算法里的搜索第一节 抓取法

选数字放入三个箱子 这种感觉

static int a[] = new int[10] ;
	static int book[] = new int[10];
	static int n = 3;//n等于几就是1-几的全排列

	static void dfs(int step) {//取数法 
		//思路 有三个位置 取数字往里面放 第一次放1 标记1没了 只有2 3以此推
		if (step == n+1) {//三个箱子为例 第四个箱子没数字了 只有3个结束
			for (int i = 1; i <= n; i++) {
				System.out.print(a[i]);
			}
			System.out.println();
			return;
		}

		for (int i = 1; i <=n; i++) {
			if (book[i] == 0) { //该数字还可以拿
				book[i] = 1;//标记 就是已经放入了箱子 拿不了
				a[step] = i;
				dfs(step + 1);
				book[i] = 0;//其实就是标记回溯
			}
		}
		return;
	}

	public static void main(String[] args) {
		dfs(1);
		/*123
          132
          213
          231
          312
          321

		 * */
		
	}

4.组合全排列


	public static void main(String[] args) {
		List<Integer> list=new ArrayList<Integer>();
		dfs(0,list);
	}

	private static void dfs(int k, List<Integer> list) {
		if (k==3) {//k=几就是几位数
			for (int x:list) {
				System.out.print(x);
			}
			System.out.println();
		}
		for (int i = 1; i <=3; i++) {//4选3 4可以是n
			 if (list.contains(i)) {
				continue;
			}
			 list.add(i);
			 dfs(k+1, list);
			 list.remove(list.size()-1);
		}
		
	}

5 3中的抓取法去重


public class dfs {
	static int a[] = new int[10] ;
	static boolean book[] = new boolean[10];
	static int n = 3;//n等于几就是1-几的全排列

	static int ss[]= {1,2,2}; //122的全排列
	static void dfs(int step) {//取数法 
		//思路 有三个位置 取数字往里面放 第一次放1 标记1没了 只有2 3以此推
		if (step == n+1) {
			for (int i = 1; i <= n; i++) {
				System.out.print(a[i]);
			}
			System.out.println();
			return;
		}

		for (int i = 0; i <3; i++) {
			//去重 *******
			if (i>0&&ss[i]==ss[i-1]&&!book[i-1]) {
				continue;
			}
			if (!book[i]) {
				book[i] = true;
				a[step] = ss[i];
				dfs(step + 1);
				book[i] = false;//其实就是标记回溯
			}
		}
		return;
	}

	public static void main(String[] args) {
		dfs(1);  /*122
                   212
                   221/
		/*123
          132
          213
          231
          312
          321

		 * */
		
	}

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱喝阔落的猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值