1. 程式人生 > >數獨問題解題報告

數獨問題解題報告

 Valid Sudoku

九宮格就是要求每一行、每一列、每一個粗線宮內的數字均含1-9,不重複。所以這裡我們的思路就是一次檢查每一行,每一列中是否有重複的數字如果有則返回false

程式碼:

class Solution {
public:
    bool isValidSudoku(vector<vector<char>>& board) {
        if(board.size()!=9||board[0].size()!=9) return false;
        //九宮格就是要求每一行、每一列、每一個粗線宮內的數字均含1-9,不重複。所以這裡我們的思路就是一次檢查每一行,每一列中是否有重複的數字如果有則返回false
        //rows
        for(int i=0;i<9;i++){
            vector<bool> used(9,false);
            for(int j=0;j<9;j++){
                if(!isdigit(board[i][j])) continue;
                int k=board[i][j]-'0';
                if(k==0 || used[k-1]) return false;
                used[k-1]=true;
            }
        }
        //cols
        for(int j=0;j<9;j++){
            vector<bool> used(9,false);
            for(int i=0;i<9;i++){
                if(!isdigit(board[i][j])) continue;
                int k=board[i][j]-'0';
                if(k==0||used[k-1]) return false;
                used[k-1]=true;
            }
        }
        //當需要分割大的變為小的,可以通過次數來進行迴圈
        for(int i=0;i<3;i++){
            //int row=3*i;
            for(int j=0;j<3;j++){
                int row=3*i;
                int col=3*j;
                vector<bool> used(9,false);
                for(int m=row;m<row+3;m++){
                    for(int n=col;n<col+3;n++){
                        if(!isdigit(board[m][n])) continue;
                        int k=board[m][n]-'0';
                        if(k==0||used[k-1]) return false;
                        used[k-1]=true;
                    }
                }
            }
        }
        return true;
    }
};
Sudoku Solver

這道題比上道題要難,因為填寫數獨我也不會==題目的做法就是一個數字一個數字的試,如果對了就再接著試下一個單元格。但是如何判斷這個數字是否正確呢,當每一行每一列和每一個小數獨中沒有出現過這個數字那就代表正確。
因此需要確定回溯變數:單元格,所以以行數和列數進行回溯
回溯條件:該單元格確定無誤,進入下一個單元格
結束回溯:回溯到最後一個單元格

class Solution {
public:
    void solveSudoku(vector<vector<char>>& board) {
        if(board.size()!=9||board[0].size()!=9) return;
        bool isFind=findSudoKu(board,0,0);
        return;
    }
    bool findSudoKu(vector<vector<char>>& board,int row,int col){
        if(row==9) return true;
        int row1;
        int col1;
        //在這裡解決的下一個單元格要訪問哪個的問題
        if(col==8){
            row1=row+1;
            col1=0;
        }
        else{
            row1=row;
            col1=col+1;
        }
        if(board[row][col]!='.'){
            if(!isValid(board,row,col)) return false;
            return findSudoKu(board,row1,col1);
        }
        
        for(int i=1;i<=9;i++){
            board[row][col]='0'+i;
            if(isValid(board,row,col)&&findSudoKu(board,row1,col1)) return true;
        }
        board[row][col]='.';
        return false;
        
    }
    bool isValid(vector<vector<char> >& board,int row,int col){
        char val=board[row][col];
        if(val<'0'||val>'9') return false;
        for(int i=0;i<9;i++){
            if(board[i][col]==val&&i!=row) return false;
            if(board[row][i]==val&&i!=col) return false;
        }
        int paneRow=row/3*3;
        int paneCol=col/3*3;
        for(int i=paneRow;i<paneRow+3;i++){
            for(int j=paneCol;j<paneCol+3;j++){
                if(board[i][j]==board[row][col]&&(i!=row||j!=col)) return false;
            }
        }
        return true;
    }
};