leetcode第51题n皇后

leetcode第51题n皇后

思路:

  1. n皇后是很经典的回溯问题,难就难在怎样进行设计,方法的划分也体挺关键的。

  2. 根据n创建一个chessboard 初始化全为’.’;

  3. 回溯的参数,分别是 n chessboard row 当n == row的时候,row - 1 行中的皇后已经填充完毕,说明我们找到了一种合理的情况,可以添加到结果集中。

  4. 回溯的过程就是从第一行开始放第一个皇后的,放在第一行的第一个位置,回溯,往第二行的第一个位置放,发现当前的位置无效,i++ 放在第二行的第二个位置,还是无效,放在第而行的第三个位置,就这样一点一点的枚举,发现有一行实在是填不进去皇后了,返回到上一行,移开当前行中填充的皇后,重新往这行放皇后(对应的是col++),当我们把每一行都填充满的时候,发现chessboard满足放置皇后的规则。

  5. 如果写验证位置是不是可以放皇后?

    1. 当前位置这一行中是不是已经有了皇后了
    2. 当前位置左上角四十五度是不是有皇后了 row- 1;col + 1
    3. 当前位置右上角一百三十五度是不是有皇后了 row - 1;col + 1

    为什么不验证当前行是不是有还有别的皇后?

    1. 每一行只放了一个皇后,就算是这个已经放置了,但是我发现在以后这种可以验证出来不合理,我就要把这个位置的皇后去掉,col++,在后一个位置放皇后。
    2. 老生常谈,皇后是一行一行的放了,想要在当前行中放皇后,就说明当前行和之后的行中,是没有皇后的。只需要检验我要防止的这个位置他的左上角和右上角是不是有皇后,有皇后,就说明我们不能这样放置。
class Solution {
    List<List<String>> res;
    public List<List<String>> solveNQueens(int n) {
        //慢慢一点点写代码吧  还是不是很容易\
        //为什么可以这么多的啊,我裂开了
        char[][] chessboard = new char[n][n];
        res = new LinkedList<>();
        for(char[] temp : chessboard){
            Arrays.fill(temp,'.');
        }
        backTrack(n,chessboard,0);
        return res;
     
    }
    void backTrack(int n,char[][] chessboard,int row){
        if(row == n){
            res.add(toList(chessboard));
            return;
        }

        for(int col = 0;col < n;col++){
            if(isValid(col,row,n,chessboard)){
                chessboard[row][col] = 'Q';
                backTrack(n,chessboard,row + 1);
                chessboard[row][col] = '.';
            }
        }
    }

    public List<String> toList(char[][] chessboard){
        List<String> helper = new LinkedList<>();
        for(char[] temp : chessboard){
            helper.add(String.copyValueOf(temp));
        }
        return helper;
    }

    public boolean isValid(int col,int row,int n,char[][] chessboard){
        //检查列
        for(int i = 0;i < row;i++){
            if(chessboard[i][col] == 'Q'){
                return false;
            }
        }
        //检查45度角上是不是有皇后
        for(int i = row - 1,j = col - 1;i >= 0 && j >= 0;i--,j--){
            if(chessboard[i][j] == 'Q'){
                return false;
            }
        }
        //检查135度角
        for(int i = row - 1,j = col + 1;i >= 0 && j < n;i--,j++){
            if(chessboard[i][j] == 'Q'){
                return false;
            }
        }

        return true;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值