数独问题

217 篇文章 0 订阅
174 篇文章 2 订阅

思路

1 对数独求解,即用回溯穷举法。遍历每一个位置,把1-9填入看是否满足。

2 按行遍历,如果这行满了就到下一行。遇到 . 就试着把1-9合适的填进去。接着便利下一个位置。

3 如何判断填入的数字是否合适。可分三种情况,行 列 宫

代码:

 void solveSudoku(vector<vector<char> > &board) {
        if(board.empty() || board.size()!=9 || board[0].size()!=9)
            return ;
        solveSuDuDFS(board,0,0);
        //solveSudokuDFS(board,0,0);
    }
    
    bool solveSuDuDFS(vector<vector<char>>& board,int row,int col){
        if(row==9)
            return true;
        if(col>=9)
            return solveSuDuDFS(board,row+1,0);  //按行遍历,
        if(board[row][col]=='.'){             //遇到。才会去试着填数
            for(int i=1;i<=9;i++){
                board[row][col]=(char)(i+'0');       //把1-9都试这填入
                if(isValidSuDu(board,row,col)){  //如果满足就接着去下一个位置
                	if(solveSuDuDFS(board,row,col+1))
                        return true;    
                }
                board[row][col]='.';       //不满足的话回溯到上一步
            }
        }else{
            return solveSuDuDFS(board,row,col+1);
        }
        return false;
    }
        bool isValidSuDu(vector<vector<char>> &board,int row,int col){
        for(int i=0;i<9;i++){
            if(row!=i&&board[row][col]==board[i][col]){  //判断 每一列 是否有相同的数字
                return false;
            }   
        }
        for(int i=0;i<9;i++){
            if(col!=i&&board[row][col]==board[row][i])  //判断每一行是否有相同的数字
                return false;
        }
        
        for(int i=row/3*3;i<row/3*3+3;i++){
            for(int j=col/3*3;j<col/3*3+3;j++){
                if((row!=i||col!=j)&&board[i][j]==board[row][col])  //判断每一个宫内是否有相同的数字
                    return false;
            }
        }
        return true;
    }
   

延伸:

判断一个数独是否是有效的数独

思路:

用hashset 的 add方法 判重复

代码1 :

   public boolean isValidSudoku(char[][] board) {
        // 每一个大循环确定一行,一列,一个九宫格
        for (int i = 0; i < 9; i++) {
            Set<Character> row = new HashSet<Character>();
            Set<Character> col = new HashSet<Character>();
            Set<Character> cube = new HashSet<Character>();
 
            for (int j = 0; j < 9; j++) {
                // 第i行
                if (board[i][j] != '.' && !row.add(board[i][j]))
                    return false;
                // 第i列
                if (board[j][i] != '.' && !col.add(board[j][i]))
                    return false;
                //
                int cubeRow = 3 * (i / 3) + j / 3, cubeCol = 3 * (i % 3) + j % 3;
                if (board[cubeRow][cubeCol] != '.' && !cube.add(board[cubeRow][cubeCol]))
                    return false;
            }
        }
        return true;
    }
代码2

 bool isValidSudoku(vector<vector<char> > &board) {
        bool flag=true;
        for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){
                char t=board[i][j];
                if(t!='.'){
                    flag=isValid(board,i,j,t);
                    if(!flag)
                        return false;
                }
            }
        }
        return flag;
    }
    bool isValid(vector<vector<char>>& board,int row,int col,char t){
        for(int i=0;i<9;i++){
            if(i!=row&&board[i][col]==board[row][col])
                return false;
        }
        for(int i=0;i<9;i++){
            if(col!=i&&board[row][col]==board[row][i])
                return false;
        }
        for(int i=row/3*3;i<row/3*3+3;i++){
            for(int j=col/3*3;j<col/3*3+3;j++){
                if((i!=row||j!=col)&&board[i][j]==board[row][col])
                    return false;
            }
        }
        return true;
    }


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值