经典深搜易错(7数排列)

这篇博客探讨了一种将排列问题转化为填数问题的深度搜索算法,以解决特定条件的数字排列。作者给出了一种以74开头的7对数字排列,要求每个数字之间间隔等于其数值。通过初始化数组并进行深度优先搜索,逐步填入数字并进行剪枝操作,最终找到符合要求的另一种排列。这种方法降低了深搜的复杂度,提高了效率。
摘要由CSDN通过智能技术生成

一、问题描述

今有7对数字:两个1,两个2,两个3,…两个7,把它们排成一行。
要求,两个1间有1个其它数字,两个2间有2个其它数字,以此类推,两个7之间有7个其它数字。如下就是一个符合要求的排列:

17126425374635
当然,如果把它倒过来,也是符合要求的。
请你找出另一种符合要求的排列法,并且这个排列法是以74开头的。

思路:(难度在于将排列问题转变为深搜填数问题)

第一思路就是深搜,找到这个排列,再依次判断是不是符合排列,但对于深搜14个数复杂度实在太高,所以我应该将深搜的思路转化为填数的思路,应该像横向走迷宫填数的思路去解决,
故我们应确定这里的深搜参数为所填的数,而不是位数

能对深搜剪枝就剪枝
7,4位已经确定,那7,4不须深搜,深搜填入两个数即可,且这两个数的距离为这个数的数值

初始化数组,0作为深搜的标记,表示未填数

	static int[] arr= {0,7,4,0,0,0,0,4,0,7,0,0,0,0,0};

注意这里为了方便取数位我们设一个大小为15的数组


  1. 依次将1~6(除4)的数填入数组下标,最后结果不符,回溯清除填入的数据
if (num>=7) {//找到了14个数
			for (int j = 1; j < arr.length; j++) {
				System.out.print(arr[j]);
			}
			return;
		}
		if (num==4) {//4不用深搜,跳过
			num++;
		}

注意这里num==4时应当选择填5,num++;

		for (int j = 3; j < 14; j++) {//从第3位开始填数,注意最后一位不可填
			if (arr[j]==0&&j+num+1<=14&&arr[j + num + 1] == 0) {
				arr[j]=num;
				arr[j+num+1]=num;
				dfs(num+1);
				arr[j]=0;
				arr[j+num+1]=0;//回溯清0;
			}
		}

代码

package competion2020;

import java.util.ArrayList;

public class 开头为74的排列法 {
	static int[] arr= {0,7,4,0,0,0,0,4,0,7,0,0,0,0,0};
	public static void main(String[] args) {
		dfs(1);//从数字1开始填

	}
	private static void dfs(int num) {
		// TODO 自动生成的方法存根
		//深搜填数类
		if (num>=7) {//找到了14个数
			for (int j = 1; j < arr.length; j++) {
				System.out.print(arr[j]);
			}
			return;
		}
		if (num==4) {//4不用深搜,跳过
			num++;
		}
		for (int j = 3; j < 14; j++) {//从第3位开始填数,注意最后一位不可填
			if (arr[j]==0&&j+num+1<=14&&arr[j + num + 1] == 0) {
				arr[j]=num;
				arr[j+num+1]=num;
				dfs(num+1);
				arr[j]=0;
				arr[j+num+1]=0;//回溯清0;
			}
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值