[LeetCode] Sudoku Solver 求解數獨

Grandyang發表於2015-04-13

 

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.

 

這道求解數獨的題是在之前那道 Valid Sudoku 驗證數獨的基礎上的延伸,之前那道題讓我們驗證給定的陣列是否為數獨陣列,這道讓我們求解數獨陣列,跟此題類似的有 Permutations 全排列Combinations 組合項 N-Queens N皇后問題等等,其中尤其是跟 N-Queens N皇后問題的解題思路及其相似,對於每個需要填數字的格子帶入1到9,每代入一個數字都判定其是否合法,如果合法就繼續下一次遞迴,結束時把數字設回'.',判斷新加入的數字是否合法時,只需要判定當前數字是否合法,不需要判定這個陣列是否為數獨陣列,因為之前加進的數字都是合法的,這樣可以使程式更加高效一些,具體實現如程式碼所示:

 

class Solution {
public:
    void solveSudoku(vector<vector<char> > &board) {
        if (board.empty() || board.size() != 9 || board[0].size() != 9) return;
        solveSudokuDFS(board, 0, 0);
    }
    bool solveSudokuDFS(vector<vector<char> > &board, int i, int j) {
        if (i == 9) return true;
        if (j >= 9) return solveSudokuDFS(board, i + 1, 0);
        if (board[i][j] == '.') {
            for (int k = 1; k <= 9; ++k) {
                board[i][j] = (char)(k + '0');
                if (isValid(board, i , j)) {
                    if (solveSudokuDFS(board, i, j + 1)) return true;
                }
                board[i][j] = '.';
            }
        } else {
            return solveSudokuDFS(board, i, j + 1);
        }
        return false;
    }
    bool isValid(vector<vector<char> > &board, int i, int j) {
        for (int col = 0; col < 9; ++col) {
            if (col != j && board[i][j] == board[i][col]) return false;
        }
        for (int row = 0; row < 9; ++row) {
            if (row != i && board[i][j] == board[row][j]) return false;
        }
        for (int row = i / 3 * 3; row < i / 3 * 3 + 3; ++row) {
            for (int col = j / 3 * 3; col < j / 3 * 3 + 3; ++col) {
                if ((row != i || col != j) && board[i][j] == board[row][col]) return false;
            }
        }
        return true;
    }
};

 

LeetCode All in One 題目講解彙總(持續更新中...)

相關文章