【LeetCode】Sudoku Solver

来源:互联网 发布:网络歌曲伤不起歌词 编辑:程序博客网 时间:2024/06/14 22:01

题目描述:

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

Empty cells are indicated by the character '.'.

You may assume that there will be only one unique solution.


A sudoku puzzle...


...and its solution numbers marked in red.

两种解法,都是DFS。

1、排除法,先对整个矩阵进行处理,记录下每个行、列、块里没有出现的值,这样在某个空位可以输入的值就是他所在位置的行、列、块的公共元素。这样效率相对较高,缺点是空间占用比较多,算就不具体算了……

2、由上一题引申出来,对每个位置填上数字然后验证是否是合法数独。当然不需要验证整个矩阵,只要验证行列块就好了。

代码如下:

方法一(153ms):

class Solution {public:void solveSudoku(vector<string> &board) {unordered_set<char> num({ '1', '2', '3', '4', '5', '6', '7', '8', '9' });vector<unordered_set<char>> m(9, num), n(9, num), B(9, num);for (int i = 0; i < 9;i++)for (int j = 0; j < 9; j++)if (board[i][j] != '.')m[i].erase(board[i][j]);for (int i = 0; i < 9; i++)for (int j = 0; j < 9; j++)if (board[j][i] != '.')n[i].erase(board[j][i]);for (int i = 0; i < 9;i+=3)for (int j = 0; j < 9; j += 3){int index = i / 3 * 3 + j / 3;for (int k = i; k < i + 3; k++)for (int l = j; l < j + 3; l++)if (board[k][l] != '.')B[index].erase(board[k][l]);}getSolution(board, m, n, B);}bool getSolution(vector<string> &board, vector<unordered_set<char>> &m, vector<unordered_set<char>> &n, vector<unordered_set<char>> &B){int i(0), j(0);for (i = 0; i < 9; i++){for (j = 0; j < 9; j++)if (board[i][j] == '.')break;if (j < 9)break;}if (i >= 9)return true;vector<char> val;int b = i / 3 * 3 + j / 3;for (unordered_set<char>::iterator iter = m[i].begin(); iter != m[i].end(); iter++)if (n[j].count(*iter) && B[b].count(*iter))val.push_back(*iter);if (val.empty())return false;for (int k = 0; k < val.size(); k++){char c = val[k];m[i].erase(c);n[j].erase(c);B[b].erase(c);board[i][j] = c;if (getSolution(board, m, n, B))return true;m[i].insert(c);n[j].insert(c);B[b].insert(c);board[i][j] = '.';}return false;}};

方法二(236ms,网上抓来的代码):

class Solution {public:    bool isValidSudoku(vector<vector<char> > &board, int x, int y) {        int row, col;                // Same value in the same column?        for (row = 0; row < 9; ++row) {            if ((x != row) && (board[row][y] == board[x][y])) {                return false;            }        }                // Same value in the same row?        for (col = 0; col < 9; ++col) {            if ((y != col) && (board[x][col] == board[x][y])) {                return false;            }        }                // Same value in the 3 * 3 block it belong to?        for (row = (x / 3) * 3; row < (x / 3 + 1) * 3; ++row) {            for (col = (y / 3) * 3; col < (y / 3 + 1) * 3; ++col) {                if ((x != row) && (y != col) && (board[row][col] == board[x][y])) {                    return false;                }            }        }                return true;    }        bool internalSolveSudoku(vector<vector<char> > &board) {        for (int row = 0; row < 9; ++row) {            for (int col = 0; col < 9; ++col) {                if ('.' == board[row][col]) {                    for (int i = 1; i <= 9; ++i) {                        board[row][col] = '0' + i;                                                if (isValidSudoku(board, row, col)) {                            if (internalSolveSudoku(board)) {                                return true;                            }                        }                                                board[row][col] = '.';                    }                                        return false;                }            }        }                return true;    }        void solveSudoku(vector<vector<char> > &board) {        internalSolveSudoku(board);    }};


0 0
原创粉丝点击