日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

每天一道LeetCode-----数独盘求解

發布時間:2024/4/19 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 每天一道LeetCode-----数独盘求解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Valid Sudoku

原題鏈接Valid Sudoku

判斷給定的數獨盤是否有效,數獨盤中可能有空位置。

簡述一下數獨的規則,參考連接Sudoku Puzzles - The Rules.

  • 每一行,數字1-9只能出現一次
  • 每一列,數字1-9只能出現一次
  • 每個3 * 3方格中,數字1-9只能出現一次。這里3 * 3方格只包括9個,即圖片中加粗黑線分開的9個方格
  • 其實就是每個點只能存在1-9這九個數字中的一個,滿足每一行,每一列,每個3 * 3方格不能出現重復的數字

    判斷一個數獨盤是否有效,只需要判斷是否滿足上述三個規則即可。另外,如果給出的數獨盤像圖片那樣有些地方沒有填充數字,也沒有關系。只需要判斷有數字的部分就好,比如說第一行只有5, 3, 7,那么可以判斷第一行沒有出現重復的數字,是滿足規則一的。


    肯定需要全部遍歷一遍,每遍歷到一個位置,就判斷它所在的行,所在的列,所在的3 * 3方格是否已經存在同樣的數字了,如果存在,返回false,否則,將這個數字添加到行,列,3 * 3方格的記錄中。
    所以需要分別記錄每一行,每一列,每一個3 * 3方格都有那些數字出現過,其實就是3個二維數組

  • 記錄每一行都出現了哪些數字,vector<vector<int>> rows(9, vector<int>(10, 0));
  • 記錄每一列都出現了哪些數字,vector<vector<int>> columns(9, vector<int>(10, 0));
  • 記錄每個3 * 3方格都出現了哪些數字,vector<vector<int>> boxes(9, vector<int>(10, 0));
  • 對于3 * 3方格,這里用vector<vector<int>> boxes(9, vector<int>(10, 0));形式表示,意思是這個數獨盤是由9個3 * 3方格,編號從0到8。對于某個位置(row, column)而言,它所在的3 * 3方格編號為row / 3 * 3 + column / 3。

    表示方法,假設當前位置為(i, j),數字為n

  • rows[i][n]表示第i行出現數字n的個數,不是1就是0
  • columns[j][n]表示第j列出現數字n的個數,不是1就是0
  • boxes[i / 3 * 3 + j / 3][n]表示當前位置所在的方格出現數字n的個數,不是1就是0
  • 代碼如下

    class Solution { public:bool isValidSudoku(vector<vector<char>>& board) {vector<vector<int>> rows(9, vector<int>(10, 0));vector<vector<int>> columns(9, vector<int>(10, 0));vector<vector<int>> boxes(9, vector<int>(10, 0));for(int i = 0; i < board.size(); ++i){for(int j = 0; j < board[i].size(); ++j){if(board[i][j] == '.')continue;int n = board[i][j] - '0';/* 如果之前有出現過(不為0),就說明數獨盤無效 */if(rows[i][n] || columns[j][n] || boxes[i / 3 * 3 + j / 3][n])return false;/* 否則,更新每一行,每一列,所在方格的內容 */elserows[i][n] = columns[j][n] = boxes[i / 3 * 3 + j / 3][n] = 1;}}return true;}};

    擴展

    Sudoku Solver

    原題鏈接Sudoku Solver

    給定一個有效的數獨盤,解出結果。
    解一個數獨盤就是要求把所有的空格都填上數字,要求仍然是滿足上述三個規則,即

  • 每一行,數字1-9只能出現一次
  • 每一列,數字1-9只能出現一次
  • 每個3 * 3方格中,數字1-9只能出現一次。這里3 * 3方格只包括9個,即圖片中加粗黑線分開的9個方格

  • 對于某個空格,它所能填充的數字需要滿足

  • 在所在行沒有出現過的
  • 在所在行沒有出現過的
  • 在所在3 * 3方格沒有出現過的
  • 所以在上面的問題中,已經把每一行,每一列,每個3 * 3方格出現的數字都找出了,接下來就是深度優先(dfs)把每個空格填上數字即可,當然填充的數字需要滿足上面的要求。
    如果填充到某個位置發現沒有可選的數字了,就說明之前的某個位置選擇錯了,就回退到之前的位置,選擇另一個滿足上述要求的數字

    代碼如下

    class Solution { public:void solveSudoku(vector<vector<char>>& board) {vector<vector<int>> rows(9, vector<int>(10, 0));vector<vector<int>> columns(9, vector<int>(10, 0));vector<vector<int>> boxes(9, vector<int>(10, 0));/* 計算每一行,每一列,每個3 * 3方格中每個數字是否出現 */for(int i = 0; i < board.size(); ++i){for(int j = 0; j < board[i].size(); ++j){if(board[i][j] == '.')continue;int n = board[i][j] - '0';rows[i][n] = columns[j][n] = boxes[i / 3 * 3 + j / 3][n] = 1;}}bool done = false;dfs(board, rows, columns, boxes, 0, 0, done); }private:void dfs(vector<vector<char>>& board, vector<vector<int>>& rows,vector<vector<int>>& columns, vector<vector<int>>& boxes,int row, int column, bool& done){/* 填充完成 */if(row >= board.size()){done = true;return;}/* 當前某一行的末尾,換到下一行 */else if(column >= board[row].size()){dfs(board, rows, columns, boxes, row + 1, 0, done);}/* 如果有數字,則不需要填充,繼續下一個 */else if(board[row][column] != '.'){dfs(board, rows, columns, boxes, row, column + 1, done);}else{for(int n = 1; n <= 9; ++n){/* 如果數字出現過,就不能填充到當前位置 */if(rows[row][n] || columns[column][n] || boxes[row / 3 * 3 + column / 3][n])continue;/* 將填充的數字記錄下來 */rows[row][n] = columns[column][n] = boxes[row / 3 * 3 + column / 3][n] = 1;board[row][column] = n + '0';/* 遞歸填充下一個空格 */dfs(board, rows, columns, boxes, row, column + 1, done);/* 如果完成,就退出 */if(done){return;}/* 否則,回到填充之前的狀態,重新找數字 */else{rows[row][n] = columns[column][n] = boxes[row / 3 * 3 + column / 3][n] = 0;board[row][column] = '.';}}}} };

    總結

    以上是生活随笔為你收集整理的每天一道LeetCode-----数独盘求解的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。