LeetCode動畫 | 36.有效的數獨

2021-02-21 程式設計師喬戈裡

今天分享一個LeetCode題,題號是36,標題是:有效的數獨,題目標籤是散列表,散列表也稱哈希表。此題解題思路用到了少量的空間換取時間的方法,降低時間上的消耗

題目描述

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

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

數獨

上圖是一個部分填充的有效的數獨。

數獨部分空格內已填入了數字,空白格用 '.' 表示。

示例 1:

輸入:
[
  ["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

示例 2:

輸入:
[
  ["8","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"]
]

輸出: false

解釋: 除了第一行的第一個數字從 5 改為 8 以外,空格內其他數字均與 示例1 相同。
     但由於位於左上角的 3x3 宮內有兩個 8 存在, 因此這個數獨是無效的。

說明:

一個有效的數獨(部分已被填充)不一定是可解的。

只需要根據以上規則,驗證已經填入的數字是否有效即可。

給定數獨序列只包含數字 1-9 和字符 '.' 。

給定數獨永遠是 9x9 形式的。

解題

此題沒有要求數獨是可解的,只要求滿足以下規則,驗證已經填入的數字是否有效即可:

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

行的下標設為i,列的下標設為j,宮格的下標設為k,默認為0,如下圖:

行、列和宮格

隨著下標i和下標j的移動,i和j可以直接從下標中獲取數字,但k如何獲取對應的數字呢?看上面圖,k隨著i變化和k隨著j變化都有規律的,不多說,直接給公式:k = (int)(i / 3) * 3 + (int)(j / 3)。

根據規則,某數字的三個下標都只能出現一次,例如8:[0,0,0],往後這個數組裡就不能再出現0了,有0出現就不符合有效數獨的規則了;再例如3:[0,1,0],i下標和k下標不能再出現0了,j下標不能再出現1了。

但怎麼判斷某數字的三個下標是否是只出現了一次呢?

題目標籤只有散列表,那正合我意,我就是要用散列表去解決此題。而且數組裡的值最小是0,最大值是8,數組的長度都固定為3,可以用少量的空間換取時間的方法,如下圖8:[0,0,0]的表示:

空間換時間

這樣就減少了兩個數組比較的煩惱,通過空間換取時間的方法,就減少了不必要的比較計算。因為行i、列j和宮格k的長度都是9,將二維數組攤開作為一維數組,下標i、下標j+9和下標k+18分別控制一維數組的下標,存放的值都是布爾類型,默認為false。

保存某數字的時候,一維數組的下標i、下標j+9和下標k+18的值都變為true。保存某數字之前,需要判斷三個下標的值是否存在true,如果不存在,則將三個下標對應的值都變為true;如果存在,說明某下標已經出現一次了,再出現一次則意味著這個數獨已經無效,直接返回false。如下圖數字8的下標k已經出現一次了。

失效的數獨

動畫:使用散列表Code:使用散列表

public boolean isValidSudoku(char[][] board) {
    // 創建散列表
    Map<Integer, boolean[]> map = new HashMap<>();
    for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
            if (board[i][j] != '.') {
                // 字符的ASCII碼 十進位
                int index = board[i][j];
                // 創建宮格標記
                int k = i / 3 * 3 + j / 3;
                // 空間換取時間
                if (!map.containsKey(index)) {
                    map.put(index, new boolean[27]); // 27個空間默認放false
                }
                // 獲取散列表的值
                boolean[] booleans = map.get(index);
                if (booleans[i] == true || booleans[j + 9] == true || booleans[k + 18] == true) {
                    return false;
                } else {
                    booleans[i] = true;
                    booleans[j + 9] = true;
                    booleans[k + 18] = true;
                }
            }
        }
    }
    return true;
}

public static void main(String[] args) {
    char[][] 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'}
    };
    boolean validSudoku = new Solution().isValidSudoku(board);
    System.out.println(validSudoku);
}

時間複雜度

時間複雜度是O(n),但實際上比O(n)要快。

相關焦點

  • LeetCode 圖解 | 36.有效的數獨
    題目來源於 LeetCode 第 36 號問題:有效的數獨.題目判斷一個 9x9 的數獨是否有效。只需要根據以下規則,驗證已經填入的數字是否有效即可。數字 1-9 在每一行只能出現一次。數字 1-9 在每一列只能出現一次。數字 1-9 在每一個以粗實線分隔的 3x3 宮內只能出現一次。
  • Leetcode No.36 有效的數獨
    一、題目描述判斷一個 9x9 的數獨是否有效。只需要根據以下規則,驗證已經填入的數字是否有效即可。
  • Leetcode 37 超越100%算法,解數獨@python
    Leetcode 37 解數獨,具體代碼見上圖,下面講一些注意點1.本題採用算法思想:交集回溯,即使用行、列、3*3矩陣已有數字,通過交集推算每個框可能的數據,然後驗證,驗證不通過回溯,直至驗證通過(1)交集推算每個框可能的數據,大字體數據為已有數據,小數字為可能的解,如下所示:數獨交集圖可能的解
  • 每天一道leetcode234-回文鍊表
    正當班主任要繼續發話,只聽到角落默默想起來一個聲音:」K2」前言 2018.11.6號打卡明天的題目:https://leetcode-cn.com/problems/remove-linked-list-elements/以後明天的題目提取公布一下哈,因為有些朋友想提前做一下~題目 leetcode234-回文鍊表中文連結:https
  • 兒童數獨遊戲入門,九宮格數獨遊戲電子版
    二十萬數獨遊戲電子版,兒童數獨遊戲入門,兒童益智遊戲,兒童邏輯思維訓練經典課程!你是否還在為孩子天天玩遊戲看電視發愁?其實,可以讓孩子玩一下數獨遊戲,數獨遊戲對孩子的好處非常多,只是很多父母意識不到,他們也不知道該怎麼教育孩子,應該教會孩子什麼?讓孩子玩數獨可以有效的鍛鍊孩子的邏輯思維能力,對數字方面的敏感度。對孩子以後初中高中在數學方面可以有一定的優勢,一旦邏輯思維能力提升,理科成績差不了。
  • 最強大腦第四季不規則數獨規則介紹 數獨技巧口訣帶圖解析
    《最強大腦》第四季最新一期的節目中,有四位數獨屆的高手前來迎接挑戰,而挑戰成功的選手就要和國外的選手進行PK了,那麼本期節目中挑戰的數獨,規則是什麼?還有玩數獨有沒有小技巧呢?數獨的口訣是什麼?和魔方差不多嗎?   本期的數獨獨pk賽戰一共兩輪,第一輪共三次比拼:第一次是標準數獨排位賽,共三題,根據三題完成時間排除四人排名。
  • 玩轉數獨之九宮數獨進階技巧
    前面我們已經學習了九宮數獨的初級技巧的兩種方法:唯一數法和隱性唯一數法。今天我們來學習九宮數獨的進階技巧:宮摒除法。
  • 每天一道leetcode56-合併區間
    正當班主任要繼續發話,只聽到角落默默想起來一個聲音:」K2」前言 2018.11.13號打卡明天的題目:https://leetcode-cn.com/problems/minimum-path-sum/descrip題目 每天一道leetcode56
  • 6歲玩數獨,12歲獲數獨世界第一,從小玩數獨的孩子有多優秀?
    相信有不少家長回答的都是「數獨」,為什麼家長都特別支持孩子玩數獨呢?因為數獨可以說是世界上公認培養數學思維最有效的遊戲之一。要想孩子數學好,數學思維可以說是必不可少的。因為數學在孩子小學階段主要考的是孩子的邏輯思維,而越是高年級越是需要孩子有良好的邏輯思維。
  • 「國育杯」思維運動會個人賽九宮數獨考驗思維靈活性及敏捷性
    「國育杯」思維運動會個人賽九宮數獨考驗思維靈活性及敏捷性 2020-08-17 10:35 來源:澎湃新聞·澎湃號·媒體
  • 數獨攻略 數獨遊戲怎麼玩
    今天為大家帶來的是數獨玩法詳解,數獨遊戲怎麼玩?感興趣的小夥伴一起來看看吧。數獨遊戲玩法  數獨遊戲,是一個九宮格,每一宮又分為九個小格。
  • 玩轉數獨之九宮數獨進階技巧解題實例
    上期我們學習了九宮數獨的進階技巧:宮摒除法,並留下了一道題目,今天我們利用這個方法來完成這個九宮數獨。請完成這個九宮數獨我們從1開始,行列延伸去尋找適用於宮摒除法的宮。完成了部分的九宮數獨這樣,整個數獨中所有的1都填寫完了。下面來看2的填法。
  • 數獨參賽十年 中國從弱隊到「前三」
    數獨遊戲常見於報紙、網頁遊戲、手機遊戲中,所需要的物理條件常常只是一張紙和一支筆,因此受到廣泛歡迎。北京市數獨運動協會副秘書長徐豔是資深的數獨愛好者,她介紹,數獨起源於18世紀初的歐洲,到了19世紀80年代,在美國成長為一種填數趣味遊戲,這就是數獨的雛形。之後,日本學者將其引入到日本,改名為「數獨」,其中「數」是數字的意思,「獨」是唯一的意思。
  • 玩轉數獨之六宮數獨初級技巧
    首先我們認識一下六宮數獨。如圖:空白的六宮數獨六宮數獨有六行六列和六宮,每行每列每宮都有六個單元格,只能1、2、3、4、5、6各出現一次。下面我們來看看填寫六宮數獨的初級技巧。行唯一法:當一行中出現了五個數字時,這一行就只剩下唯一的一個數字可以填寫了。
  • 《經典的數獨》好玩嗎?怎麼玩?經典的數獨遊戲介紹
    導 讀 導讀:期待已久的熱門手遊經典的數獨火爆來襲啦!
  • 經典九宮格數獨
    相信很多小夥伴對於數獨遊戲都不陌生,這款遊戲可以說是休閒遊戲的扛把子,而經典九宮格數獨便是最新推出的一款基於數獨經典玩法的遊戲,這款遊戲經過了全新的畫面設計,帶來了不一樣的視覺觀感體驗,同時延續了經典的數獨玩法,帶給你別樣的遊戲樂趣。
  • 數獨競賽題小遊戲 數獨快速計算公式解題方法
    數獨的元素 數獨的元素主要包括行、列和宮。這三者劃分出數獨有三種不同形態的區域,而數獨規則就是要求在這些區域內出現的數字都為1~9。 元素坐標圖: 行:數獨盤面內橫向一組九格的區域,用字母表示其位置; 列:數獨盤面內縱向一組九格的區域
  • 數獨遊戲怎麼玩
    工具/原料紙,筆,數獨題數獨一:數獨的玩法。數獨的玩法比較多,比較常見也是我們經常玩的是九宮格。另外還有變形數獨,包括對角線數獨,鋸齒數獨,killer數獨(也稱為殺手數獨)等。二:數獨的規則。其實數獨的規則很簡單,顧名思義——數獨中每個數字只能出現一次。數獨盤面是個九宮,每一宮又分為九個小格。
  • 每天一道數獨題,佳學慧帶你由淺入深學數獨
    相信家長們都會有這樣的經歷,在培訓班或者在網上看到有人宣傳練習數獨的好處,就抱著好奇的心態買了一套數獨盤或者數獨練習冊。但是在連猜帶蒙做了兩道題後就被卡住了。看到練習冊上明明寫的是簡單級別的題,開始懷疑人生。久而久之買來的數獨盤或者練習冊就開始躺在角落裡吃灰了。
  • 玩轉數獨之九宮數獨初級技巧解題實例
    上次我們講了九宮數獨初級技巧玩轉數獨之標準九宮數獨初級技巧,並留下了一道題,今天我們來將這道題完整的解出來。完成了部分的九宮數獨繼續觀察,尋找只有一個空格的行、列、宮,發現:第一行只有一個空格,出現了8、2、3、7、6、