代码随想录打卡第30天|51. N皇后;37. 解数独

51. N皇后

关键点1:结束条件,当 row==n 时,代表遍历完所有行了,可以直接返回根节点的结果了

关键点2:单层循环条件

2-1:每行的行是固定的,相当于变化的是col,去确定每行具体放哪个位置:;

2-2:需要有一个判断放的位置是否合法的函数,调用函数,如果合法,则chessBoard[row][col] = 'Q';然后递归到下一层,row+1,然后chessBoard[row][col] = '.'

关键点3:判断放的位置是否合法的函数

3-1:每行只加一个,所以只有判断列是否符合条件;

3-2:判断左45度是否符合条件,条件用与:i >=0 && j>= 0;

3-3:判断右135度是否符合条件,条件用与:i >=0 && j < n;

关键点4:将char[][] 转化为List<String>,以便加入后面的res

class Solution {
    List<List<String>> res = new ArrayList<>();
    public List<List<String>> solveNQueens(int n) {
        char[][] chessBoard = new char[n][n];
        // 初始化chessBoard数组
        for(char[] i:chessBoard){
            Arrays.fill(i,'.');
        }
        backTracking(chessBoard,n,0);
        return res;
    }
    public void backTracking(char[][] chessBoard,int n,int row){
        // 结束条件
        if(row == n){
            res.add(Array2List(chessBoard));
            return;
        }

        // 单层循环条件
        for(int col = 0; col < n; col++){
            if(isQ(row,col,chessBoard,n)){
                chessBoard[row][col] = 'Q';
                backTracking(chessBoard,n,row+1);
                chessBoard[row][col] = '.';
            }
        }
    }
    // 将char[][] 转化为List<String>
    public List Array2List(char[][] chessboard) {
        List<String> list = new ArrayList<>();

        for (char[] c : chessboard) {
            list.add(String.copyValueOf(c));
        }
        return list;
    }
    public boolean isQ(int row,int col,char[][] chessBoard,int n){
        // 每行只加一个,所以只有判断列是否符合条件
        for(int i =0; i < row;i++ ){
            if(chessBoard[i][col] =='Q'){
                return false;
            }
        }        

        // 判断左45度是否符合条件,条件用与:i >=0 && j>= 0;
        for(int i =row-1,j = col-1; i >=0 && j>= 0;i--,j-- ){
            if(chessBoard[i][j] =='Q'){
                return false;
            }
        }  

        // 判断右135度是否符合条件,条件用与:i >=0 && j < n;
        for(int i = row-1,j = col+1; i >= 0 && j < n;i--,j++){
            if(chessBoard[i][j] =='Q'){
                return false;
            }
        } 
        return true;
    }
}

37. 解数独 

 关键点1:

1-1:两层for 遍历行,遍历列,确定每个格子的元素;

1-2:用if(board[i][j] == '.')判断这个位置放k是否合适;

1-3:用for循环将k='1'遍历到k='9',判断是否满足条件,不满足则循环结束返回false;

1-4:循环内部需要判断:这个board[i][j]位置放k是否合适,写一个判断k是否合适的函数;如果合适,就把k值给这个位置,递归,进入下一个位置的判断,再将这个位置的值改为'.'

1-5:两层for遍历完都没有返回false,说明找到了合适棋盘位置了,在循环结束返回TRUE;         

关键点2:判断k是否合适的函数

2-1:同行是否重复,行不变,列++;

2-2:同列是否重复:列不变,行++;

2-3:九宫格是否重复

1)确定此时行列位置初始行和初始列的位置 int startRow = (row / 3) * 3; int startCol = (col / 3) * 3;

2)两层for循环i,j遍历9宫格的元素,如果有元素和k的值相同,则返回false,否则循环结束,返回true;

int i = startRow; i < startRow + 3; i++;int j = startCol; j < startCol+ 3; j++

 

class Solution {
    public void solveSudoku(char[][] board) {
        backTracking(board);
    }

    public boolean backTracking(char[][] board){
        for(int i = 0;i < board.length;i++){// 遍历行
            for(int j = 0 ;j < board.length;j++){// 遍历列
                if (board[i][j] != '.'){ // 跳过原始数字
                    continue;
                }
                if(board[i][j] == '.'){ // 这个位置放k是否合适
                    for(char k = '1';k <= '9';k++){
                        if(isT(board,i,j,k)){
                            board[i][j] = k;
                            //如果找到合适一组立刻返回
                            if (backTracking(board)){ 
                            return true;
                            }
                            board[i][j] = '.';
                        }
                    }
                    // 如果9个数都尝试都不行,证明有空没办法填上,肯定返回FALSE
                    return false;
                }
               
            }
        }
        // 遍历完没有返回false,说明找到了合适棋盘位置了
        return true;
    }
    public boolean isT(char[][] board,int row,int col,char k){
     //判断棋盘是否合法有如下三个维度:

     // 同行是否重复
        for (int j = 0; j < 9; j++){
            if (board[row][j] == k){
                return false;
            }
        }
        // 同列是否重复
        for (int i = 0; i < 9; i++){
            if (board[i][col] == k){
                return false;
            }
        }
        // 9宫格里是否重复
        int startRow = (row / 3) * 3;
        int startCol = (col / 3) * 3;
        for (int i = startRow; i < startRow + 3; i++){
            for (int j = startCol; j < startCol + 3; j++){
                if (board[i][j] == k){
                    return false;
                }
            }
        }
        return true;
    }

}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值