1. 程式人生 > 其它 >LeetCode 37. 解數獨

LeetCode 37. 解數獨

技術標籤:Leetcode解題思路(C++實現)回溯演算法

描述

編寫一個程式,通過填充空格來解決數獨問題。

一個數獨的解法需遵循如下規則:
數字 1-9 在每一行只能出現一次。
數字 1-9 在每一列只能出現一次。
數字 1-9 在每一個以粗實線分隔的 3x3 宮內只能出現一次。

空白格用 ‘.’ 表示。

在這裡插入圖片描述

一個數獨。

在這裡插入圖片描述

答案被標成紅色。

提示:

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

思路

  • 這道題做了一天沒解出來…哎,好難,最終還是看了答案。
  • 解數獨是回溯演算法的經典應用。這道題要注意題設一點:答案唯一。也就是說,回溯時只要找到一個答案,程式就可以結束了。為了達到此目的,將回溯函式返回值設為bool,當找到答案時返回true,不再繼續遞迴。
  • 從第0行0列開始遍歷,先遍歷第0行的每一列,然後遍歷第1行的每一列…如此直到row=9時超出網格範圍,遞迴結束。
  • 對於某些網格,如果為空,才從1~9開始遍歷往裡填,如果已經有值了,那麼直接跳過此格子,進入本行的下一個格子。
  • 需要寫一個函式,判斷當前格子的同行、同列,本宮(3x3格子)內是否已經有此元素,沒有才能放,有的話跳過。

解答

class Solution {
public:
    void solveSudoku(vector<vector<char>>& board) {
        backTrack(board, 0, 0);//從第0行0列開始遞迴
    }

    bool
backTrack(vector<vector<char>>& board, int row, int column){ if(row == 9) return true;//row=9說明找到了正確結果 if(column == 9) return backTrack(board, row + 1, 0);//column=9,則開始下一行,必須return,否則下面程式碼還會執行 if(board[row][column] == '.'){ for
(char i = '1';i <= '9'; ++ i){ if(isInBoard(board, row, column, i) == false){//當前數可填入 board[row][column] = i; if(backTrack(board, row, column + 1)) return true;//找到結果,結束程式 board[row][column] = '.'; } } }else{ //本層得到後續遞迴的結果拋給上一層,不return會執行下面的return false,將false拋給上層 return backTrack(board, row, column + 1); } return false;//能執行到這步,說明遍歷完1~9也沒找到合適的數,則失敗。 } //查詢某個數是否已經在本行、本列、本宮記憶體在,已存在則返回true bool isInBoard(vector<vector<char>>& board, int row, int column, char target){ for(int k = 0;k < 9; ++ k){ if(board[row][k] == target || board[k][column] == target || board[(row / 3) * 3 + k / 3][(column / 3) * 3 + k % 3] == target) return true; } return false; } };