LeetCode37-解數獨

1 題目描述

編寫一個程序,通過已填充的空格來解決數獨問題。一個數獨的解法需遵循如下規則:

  • 數字 1-9 在每一行只能出現一次。
  • 數字 1-9 在每一列只能出現一次。
  • 數字 1-9 在每一個以粗實線分隔的 3x3 宮內只能出現一次。
  • 空白格用 ‘.’ 表示。

Note:

  • 給定的數獨序列只包含數字 1-9 和字符 '.'
  • 你可以假設給定的數獨只有唯一解。
  • 給定數獨永遠是 9x9 形式的。

2 題解

解數獨基本沒有特別好的方法,讓笨笨的計算機去解數獨它只會回溯。大致的思路:遞歸求解數獨就按照從左往右從上往下的順序逐個試過去,如果不符合數獨的規則則回溯到上一個狀態。

小trick

在進行回溯之前,先遍歷一遍數獨矩陣,將空位置的座標記下來,在回溯的時候逐個訪問空座標。話不多說,直接看代碼吧:

C++代碼

class Solution {
public:
    bool check(vector<vector<char>> & board, int row, int col) {
        // check row
        for (int i = 0; i < 9; i++) 
            if (i != col && board[row][i] == board[row][col]) return false;
        // check col
        for (int i = 0; i < 9; i++) 
            if (i != row && board[i][col] == board[row][col]) return false;
        // check block
        for (int i = (col / 3) * 3; i < (col / 3) * 3 + 3; i++) {
            for (int j = (row / 3) * 3; j < (row / 3) * 3 + 3; j++) {
                if (i != col && j != row && board[j][i] == board[row][col]) return false;
            }
        }
        return true;
    }

    bool helper(vector<vector<char>>& board, vector<int> &blank_list, int index) {
        if (index == blank_list.size()) {
            return true;
        }

        int row = blank_list[index] / 9;
        int col = blank_list[index] % 9;
		bool ret = false;
        for (int i = 1; i <= 9; i++) {
            board[row][col] = '0' + i;
            if (ret == false && check(board, row, col)) 
                ret = helper(board, blank_list, index + 1);
            if (ret == true) 
                return true; 
			board[row][col] = '.';
        }
		return false;
    }

    void solveSudoku(vector<vector<char>>& board) {
        vector<int> blank_list;
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                if (board[i][j] == '.') blank_list.push_back(i * 9 + j);
            }
        }
        helper(board, blank_list, 0);
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章