漫画:算法如何验证合法数独 | 全世界最难的数独?
今天是小浩算法 “365刷題計劃” 第95天 。數獨相信在座的各位都玩過,那我們如何使用程序去驗證一個 9×9 的數獨是有效的呢?一起看下!
01
PART
有效的數獨
數獨是源自18世紀瑞士的一種數學游戲。是一種運用紙、筆進行演算的邏輯游戲。玩家需要根據 9×9 盤面上的已知數字,推理出所有剩余空格的數字,并滿足每一行、每一列、每一個粗線宮(3*3)內的數字均含1-9,不重復。
有效的數獨:判斷一個 9x9 的數獨是否有效。只需要根據以下規則,驗證已經填入的數字是否有效即可。
數字 1-9 在每一行只能出現一次。
數字 1-9 在每一列只能出現一次。
數字 1-9 在每一個以粗實線分隔的 3x3 宮內只能出現一次。
比如輸入:
[
? ["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
數獨部分空格內已填入了數字,空白格用 '.' 表示。
說明:
一個有效的數獨(部分已被填充)不一定是可解的。
只需要根據以上規則,驗證已經填入的數字是否有效即可。
給定數獨序列只包含數字 1-9 和字符 '.' 。
給定數獨永遠是 9x9 形式的。
畫出來就是下面這樣:
02
PART
題解分析
聊聊數獨,很早之前其實研究過一陣子,還是非常有趣的。解法有很多,包括什么余數法,摒除法等等。那我們如何去評定一個數獨的難度呢?一般情況下,給定的數字個數越多,數獨相對越簡單。
解題的關鍵題目中其實已經說了:
數字 1-9 在每一行只能出現一次。
數字 1-9 在每一列只能出現一次。
數字 1-9 在每一個以粗實線分隔的 3x3 宮內只能出現一次。
我們要做的就是用程序來完成這個驗證的過程,如何驗證?那其實就兩步:
第一步:遍歷數獨中的每一個元素
第二步:驗證該元素是否滿足上述條件
遍歷這個沒什么好說的,從左到右,從上到下進行遍歷即可。就一個兩層循環。因為題目本身就是常數級的規模,所以時間復雜度就是 O(1)。
問題來了:如何驗證元素在 行 / 列 / 子數獨中沒有重復項?
其實很簡單,我們建立三個數組分別記錄每行,每列,每個子數獨(子數獨就是上面各種顏色的小框框)中出現的數字。
1//JAVA 2int[][]?rows?=?new?int[9][9]; 3int[][]?col?=?new?int[9][9]; 4int[][]?sbox?=?new?int[9][9];當然,剛開始的時候他們都是空的。然后每遍歷到一個元素,我們就看看這個元素在里邊存不存在,不存在就放進去,存在那說明數獨不合法。
舉個栗子,比如這個數獨。第6行5列為2,那我們就對 rows 和 col 進行設置:(1表示元素存在)
rows[當前行][當前元素值] = rows[5][2] = 1
col[當前列][當前元素值] = col[4][2] = 1
但是這里有個問題,如果元素值是 9,那就越界了!所以我們對當前元素值減個一處理一下:
rows[當前行][當前元素值] = rows[5][2-1] = 1
col[當前列][當前元素值] = col[4][2-1] = 1
現在的題是,對于 sbox 該如何設置呢?我們用下面的公式來計算得到:
boxIndex = (row / 3) * 3 + columns / 3其實很容易理解:我們把上面的第6行5列代入到這個公式里,(5 / 3) * 3 + 4 / 3 = 3 + 1 = 4。這個 4 也就代表最終落到 4 的這個小區域中。
我猜有人不能理解這個算式(是的,連公式都稱不上),所以我再解釋一下它是怎么來的。比如上面的第 6 行,row 為 5,5/3=1 可以理解為 此時在第1大行上,然后 (5/3)*3,是計算出當前第一大行處的 boxIndex 值。最后再加上的 4/3,意思是向右偏移幾個大列。
根據分析,給出代碼:
鄭重申明(讀我的文章必看):
本系列所有教程都不會用到復雜的語言特性,大家無須擔心沒有學過相關語法,算法思想才是最重要的!
作為學術文章,雖然風格可以風趣,但嚴謹,我是認真的。本文所有代碼均在leetcode進行過測試運行。
03
PART
啰嗦一下
母親節快樂~
最后,我在這里分享給大家一個很難很難的數獨,歡迎大家來挑戰!!挑戰成功的,評論區留下你的答案!
好了,今天的題目就講完了,我覺得講的還是挺好的。大家要是認為ok的話,給我來個轉發吧~感謝!如果想看其他面試題相關內容的,可以看:
漫畫:知乎面試題(旋轉數組最小值Ⅰ - 基礎版)
漫畫:知乎面試題(旋轉數組最小值Ⅱ - 進階版)
漫畫:美團面試題(TOPK:求第K個最大的元素)
漫畫:騰訊面試題(面試官問我會不會修供暖器,我說沒問題)
漫畫:位運算技巧整理匯總+一道被嫌棄的題目
如果你問我對學習算法有什么建議,這篇文章是必看的:
漫畫:小白為了面試如何刷題?(嘔心瀝血算法指導篇)
漫畫:嘔心泣血算法指導篇(真正的干貨,怒懟那些說算法沒用的人)
?小浩算法,每日一題
關注領取《圖解算法題》高清版
進群的小伙伴請加右側私人微信(備注:進群)
總結
以上是生活随笔為你收集整理的漫画:算法如何验证合法数独 | 全世界最难的数独?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 惠康游戏手柄 WE-8400 Windo
- 下一篇: Robots协议(摘)