Leetcode 37. 解数独(困难) 回溯算法

labuladong讲解

 

37. 解数独(困难)

题目:

数独部分空格内已填入了数字,空白格用 '.' 表示。
 
思路:
输入是一个9x9的棋盘,空白格子用点号字符 . 表示,算法需要在原地修改棋盘,将空白格子填上数字,得到一个可行解。
当 col 到达超过每一行的最后一个索引时,转为增加 row 开始穷举下一行,并且在穷举之前添加一个判断,跳过不满足条件的数字
当 row == m 的时候就说明穷举完了最后一行,完成了所有的穷举,就是 base case。
 
class Solution {
public:
    void solveSudoku(vector<vector<char>>& board) {
        backtrack(board,0,0);
    }
    bool backtrack(vector<vector<char>>& board, int row, int col){
        int m=9,n=9;
        if(col==n){
            // 穷举到最后一列的话就换到下一行重新开始。
            return backtrack(board,row+1,0);
        }
        if(row==m){
            // 找到一个可行解,触发 base case
            return true;
        }
        if(board[row][col]!='.'){
            // 如果有预设数字,不用我们穷举
            return backtrack(board,row,col+1);
        }
        for(char ch='1';ch<='9';ch++){
            // 如果遇到不合法的数字,就跳过
            if(!isValid(board,row,col,ch)){
                continue;
            }
            board[row][col]=ch;
            // 如果找到一个可行解,立即结束
            if(backtrack(board,row,col+1)){
                return true;
            }
            board[row][col]='.';
        }
        // 穷举完 1~9,依然没有找到可行解,此路不通
        return false;
    }
    // 判断 board[r][c] 是否可以填入 ch
    bool isValid(vector<vector<char>>& board,int row,int col,char ch){
        for(int i=0;i<9;++i){
            // 判断行是否存在重复
            if(board[row][i]==ch){
                return false;
            }
            // 判断列是否存在重复
            if(board[i][col]==ch){
                return false;
            }
            // 判断 3 x 3 方框是否存在重复
            int suqare_row=(row/3)*3+i/3;
            int suqare_col=(col/3)*3+i%3;
            if(board[suqare_row][suqare_col]==ch){
                return false;
            }
        }
        return true;
    }
};

 

posted @ 2022-03-07 20:07  鸭子船长  阅读(80)  评论(0编辑  收藏  举报