• LeetCode 37. Sudoku Solver II 解数独 (C++/Java)


    题目:

    Write a program to solve a Sudoku puzzle by filling the empty cells.

    A sudoku solution must satisfy all of the following rules:

    1. Each of the digits 1-9 must occur exactly once in each row.
    2. Each of the digits 1-9 must occur exactly once in each column.
    3. Each of the the digits 1-9 must occur exactly once in each of the 9 3x3sub-boxes of the grid.

    Empty cells are indicated by the character '.'.


    A sudoku puzzle...


    ...and its solution numbers marked in red.

    Note:

    • The given board contain only digits 1-9 and the character '.'.
    • You may assume that the given Sudoku puzzle will have a single unique solution.
    • The given board size is always 9x9.

    分析:

    数独应该很多人都有玩过,其规则是每列,每行,每个九宫格数字都是1-9,且没有重复的。

    那么这道题的解法就是在数独中依次添加1-9,同时判断是否符合条件,如果不符合就回溯,符合条件就在下个格子填数字。可以维护几个数组,用来标记哪行哪列哪个九宫格中的数字是否被使用过。

    程序:

    C++

    class Solution {
    public:
        void solveSudoku(vector<vector<char>>& board) {
            cols = vector<vector<int>>(9, vector<int>(10, 0));
            rows = vector<vector<int>>(9, vector<int>(10, 0));
            //boxs index
            // 0, 1, 2
            // 3, 4, 5
            // 6, 7, 8
            boxs = vector<vector<int>>(9, vector<int>(10, 0));
            for(int i = 0; i < board.size(); ++i){
                for(int j = 0; j < board[i].size(); ++j){
                    if(board[i][j] != '.'){
                        int k = board[i][j] - '0';
                        rows[i][k] = 1;
                        cols[j][k] = 1;
                        int bx = i / 3;
                        int by = j / 3;
                        boxs[bx + by * 3][k] = 1;
                    }
                }
            }
            dfs(board, 0, 0);
        }
    private:
        vector<vector<int>> cols, rows, boxs;
        bool dfs(vector<vector<char>>& board, int r, int c){
            if(r == 9)
                return true;
            int nextR = r;
            int nextC = (c + 1) % 9;
            if(nextC == 0)
                nextR = r + 1;
            if(board[r][c] != '.')
                return dfs(board, nextR, nextC); 
            for(int i = 1; i <= 9; ++i){
                int bx = r / 3;
                int by = c / 3;
                int boxIndex = bx + by * 3;
                if(!rows[r][i] && !cols[c][i] && !boxs[boxIndex][i]){
                    rows[r][i] = 1;
                    cols[c][i] = 1;
                    boxs[boxIndex][i] = 1;
                    board[r][c] = i + '0';
                    if(dfs(board, nextR, nextC))
                        return true;
                    rows[r][i] = 0;
                    cols[c][i] = 0;
                    boxs[boxIndex][i] = 0;
                    board[r][c] = '.';
                }
            }
            return false;
        }
    };

    Java

    class Solution {
        public void solveSudoku(char[][] board) {
            rows = new int[9][10];
            cols = new int[9][10];
            boxs = new int[9][10];
            for(int i = 0; i < board.length; ++i){
                for(int j = 0; j < board[i].length; ++j){
                    if(board[i][j] != '.'){
                        int k = board[i][j] - '0';
                        rows[i][k] = 1;
                        cols[j][k] = 1;
                        int bx = i / 3;
                        int by = j / 3;
                        boxs[bx + by * 3][k] = 1;
                    }
                }
            }
            dfs(board, 0, 0);
        }
        private boolean dfs(char[][] board, int r, int c){
            if(r == 9)
                return true;
            int nextR = r;
            int nextC = (c + 1) % 9;
            if(nextC == 0)
                nextR = r + 1;
            if(board[r][c] != '.')
                return dfs(board, nextR, nextC); 
            for(int i = 1; i <= 9; ++i){
                int bx = r / 3;
                int by = c / 3;
                int boxIndex = bx + by * 3;
                if(rows[r][i] == 0 && cols[c][i] == 0 && boxs[boxIndex][i] == 0){
                    rows[r][i] = 1;
                    cols[c][i] = 1;
                    boxs[boxIndex][i] = 1;
                    board[r][c] = (char)(i + '0');
                    if(dfs(board, nextR, nextC))
                        return true;
                    rows[r][i] = 0;
                    cols[c][i] = 0;
                    boxs[boxIndex][i] = 0;
                    board[r][c] = '.';
                }
            }
            return false;
        }
        private int[][] rows;
        private int[][] cols;
        private int[][] boxs;
    }
  • 相关阅读:
    ES5 ES6 作用域声明部分
    js 内建函数reduce
    $apply的使用与否
    得分-星星
    CSS3中translate、transform和translation的区别和联系
    vue 学习笔记
    -webkit-line-clamp 多行文字溢出...
    八位二进制数为什么表示范围(-128~~+127)理解
    vs2017_enterprise正式版离线安装包bt下载
    RSA密钥之C#格式与Java格式转换
  • 原文地址:https://www.cnblogs.com/silentteller/p/12372555.html
Copyright © 2020-2023  润新知