1. 程式人生 > 其它 >LeetCode:有效的數獨

LeetCode:有效的數獨

題目描述

請你判斷一個9 x 9 的數獨是否有效。只需要 根據以下規則 ,驗證已經填入的數字是否有效即可。

數字1-9在每一行只能出現一次。

數字1-9在每一列只能出現一次。

數字1-9在每一個以粗實線分隔的3x3宮內只能出現一次。

作者:力扣 (LeetCode)

連結:https://leetcode-cn.com/leetbook/read/top-interview-questions-easy/x2f9gg/

來源:力扣(LeetCode)

著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

題目解析

例,輸入如下資料

輸入:board =

[["5","3",".",".","7",".",".",".","."]

,["6",".",".","1","9","5",".",".","."]

,[".","9","8",".",".",".",".","6","."]

,["8",".",".",".","6",".",".",".","3"]

,["4",".",".","8",".","3",".",".","1"]

,["7",".",".",".","2",".",".",".","6"]

,[".","6",".",".",".",".","2","8","."]

,[".",".",".","4","1","9",".",".","5"]

,[".",".",".",".","8",".",".","7","9"]]

輸出:true

  這個題目怎麼去分析呢?首先它有9行,9列,9個小四方塊,最簡單的方法我們弄27個HashMap也能解決該問題,但它不是最優解。怎樣才能找到最優解呢?先分拆問題,將問題簡單化,解決簡單問題找到規律後再解決原有問題。如果只有一行9個數字,我們怎麼判斷它是否有重複的呢?我們順著前面那個暴力破解的思路來分析,當然我們可以使用HashMap來解決,但是組合問題後,解題方式又變成剛才的解法了。

為了引出解題方法,我們先將一個故事,前些日子我陪女兒玩過一個這樣的遊戲:面前有7個杯子和七個球,杯子和球的顏色一一對應,需要把球放到相同顏色的杯子了。對這個遊戲我們做一下延申,標有1-9的數字的杯子和標有1-9的數字的小球,將小球放到相同數字的杯子裡,如果有很多小球呢?我們是不是能夠快速的確定手裡的小球有沒有重複的呢?

通過上面的遊戲,我們可以想象到如果把數獨裡的數字當成Key存在HashMap中,如果把這個數字當成Index索引,作為陣列的下標也可以解決這個問題,這樣我們只需要三個9*9的二位陣列即可。我們首先定義一個代表所有行的陣列:row[9][9],用i表示哪一行,用數獨裡的字元表示j,如果原始陣列中存在i上不等於'.'的數字num,那麼將num放著i行的num列,這裡我們將row[i][num]置為1,代表這個行列已經存在值了。同理,我們定義colunm[9][9] ,用j表示第幾列,賦值給該陣列的行下標,num的處理同row。

  接下來我們定義9個區塊的陣列:block[9][9],首先,我們用block的每一行放置每一小塊的原始元素,其次,我們要確認原始陣列的那個元素屬於哪一行block。通過分析可以得到index=i/3+j/3*3,index表示block那一行

  最後我們需要注意一點,原始陣列的元素為char型別,因此我們想要得到對應的int型別的數字需要進行acsii轉換num=char-'0'-1;我們用原始元素-1,是為了將元素轉為數字下標,這樣處理不應用驗證重複的邏輯

題目解答

演算法1,時間複雜度為 o(n²),直接上程式碼如下:

int row[9][9];
        int colunm[9][9];
        int block[9][9];
    bool isValidSudoku(vector<vector<char>>& board) {
        
       for(int i=0;i<9;i++)
       {
           for(int j=0;j<9;j++)
           {
               if(board[i][j]=='.')
               {
                   continue;
               }
               int num=board[i][j]-'0'-1;
               int bindex=i/3+j/3*3;
                if(row[i][num]!=0 || colunm[j][num]!=0 || block[bindex][num]!=0)
               {
                   return false;
               }
               row[i][num]=colunm[j][num]=block[bindex][num]=1;
              
           }
       }
       return true;
    }

解題思路:解題思路再題目分析中已經詳細闡明,此次不再累述。