LeetCode37 Sudoku Solver 解数独问题

问题描述:
Write a program to solve a Sudoku puzzle by filling the empty cells.

A sudoku solution must satisfy all of the following rules:

Each of the digits 1-9 must occur exactly once in each row.
Each of the digits 1-9 must occur exactly once in each column.
Each of the the digits 1-9 must occur exactly once in each of the 9 3x3 sub-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.
题源:here;完整实现:here
思路:
自己写一个程序解数独问题!挺有意思。首先我们使用三个矩阵来记录数独中的约束:

    vector<vector<bool>> areaMap;
    vector<vector<bool>> rowMap;
    vector<vector<bool>> colMap;

areaMap:记录3×3的子矩阵中哪些数被占据
rowMap:记录每一行中哪些数被占据
colMap:记录每一列中哪些数被占据
如果某个数在以上三个位置都不存在,则是可能被填上的数,我们的程序就是不断的尝试那些可能被填上的数,当然是通过递归的方式。
为了方便记录填补的位置,我们使用一个变量fillNum来表征在填补第几个位置,当然需要将其转换为行列数,当fillNum >= 81时我们认为数独游戏完成。
最后贴出完整实现:

class Solution {
public:
    vector<vector<bool>> areaMap;
    vector<vector<bool>> rowMap;
    vector<vector<bool>> colMap;

    bool initMaps(vector<vector<char>> board){
        areaMap = vector<vector<bool>>(9, vector<bool>(9, false));
        rowMap = vector<vector<bool>>(9, vector<bool>(9, false));
        colMap = vector<vector<bool>>(9, vector<bool>(9, false));

        for (int i = 0; i < 9; i++){
            for (int j = 0; j < 9; j++){
                if (board[i][j] == '.') continue;
                int digit = board[i][j] - '1';
                int areaIdx = i / 3 + j / 3 * 3;
                if (areaMap[areaIdx][digit] || rowMap[i][digit] || colMap[j][digit]) return false;
                areaMap[areaIdx][digit] = rowMap[i][digit] = colMap[j][digit] = true;
            }
        }

        return true;
    }

    bool fillBoard(vector<vector<char>>& board, int fillNum){
        if (fillNum >= 81) return true;
        int rowFill = fillNum / 9;
        int colFill = fillNum % 9;
        if (board[rowFill][colFill] != '.') return fillBoard(board, fillNum + 1);

        for (int i = 0; i < 9; i++){
            int areaIdx = rowFill / 3 + colFill / 3 * 3;
            int digit = i;
            if (areaMap[areaIdx][digit] || rowMap[rowFill][digit] || colMap[colFill][digit]) continue;
            board[rowFill][colFill] = '1'+i;
            areaMap[areaIdx][digit] = rowMap[rowFill][digit] = colMap[colFill][digit] = true;

            if (fillBoard(board, fillNum + 1)) return true;
            board[rowFill][colFill] = '.';
            areaMap[areaIdx][digit] = rowMap[rowFill][digit] = colMap[colFill][digit] = false;
        }

        return false;
    }

    void solveSudoku(vector<vector<char>>& board) {
        if (!initMaps(board)) return;
        bool result = fillBoard(board, 0);
    }
};

你可能感兴趣的:(LeetCode实践)