专题四:综合练习(最经典的回溯题之N皇后详解)

以leetcode51题为例

题目分析:

下过国际象棋的都知道,皇后可以在它所在的行,所在的列,还有所在的斜线进行移动

这道题就是给n个皇后,nxn的棋盘,让这n个皇后不能互相吃彼此

算法原理分析: 

一、在画决策树之前,我们要想明白,什么样的皇后位置为合法的

      1.首先它能够一行和一列,所以我们是每一行一个皇后,每一列一个皇后

      2.对角线只能有一个皇后

二、基于以上的理解,我们就可以自己尝试画一下决策树(以下以N=3画)

就是想明白怎么剪枝就行,难点就在这里

dfs函数:你告诉dfs一个行数,dfs就尝试是否能在这一行放皇后,如果能放就放,然后考虑下一层

 递归出口:当行数越界的时候收集结果

这里要重点考虑剪枝,如何剪枝???

无非就是想,考虑这个位置能不能放上皇后

1.无脑方法:四次循环,第一次循环寻找这一行有没有皇后,第二次寻找这一列有没有皇后

                                       第三次寻找主对角线有没有皇后,第四次寻找副对角线有没有皇后

                     但是每个位置都进行四次循环时间复杂度很高(可以小优化,不要循环行,因为我们

                     是一行一行的枚举的,当回溯到一行的时候,一行的每个位置都是合法的 )

2.类似哈希表的策略:三个数组表示,列/对角线有没有皇后

                                  bool col[n]:当第0行有皇后时,我们可以col[0]=true;

                                 行就不要表示了,因为我枚举行的时候都是合法的

                                那对角线怎么表示呢???这需要联想高中数学知识,坐标即可

                                 主对角线:y=x+b   ->   y-x=b  此时发现纵坐标-横坐标为定值

                                那我们可以bool dig1[2xn]:当y-x=b,把b对应的设为true,dig1[b]=true

                                但是此时我们又发现一个问题?y-x可能是负数,那dig1就可以越界

                               可以加上一个偏移量,x最大为n,y最小为0,y-x+n=b+n即可

                                同理,副对角线也可以这样表示

代码编写:

 

                      

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值