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;
}

 

posted @ 2020-02-27 15:53  silentteller  阅读(242)  评论(0编辑  收藏  举报