数独问题解题报告

 Valid Sudoku

https://leetcode.com/problems/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

https://leetcode.com/problems/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;
    }
};



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值