一、題目
判斷一個 9x9 的數獨是否有效。只需要根據以下規則,驗證已經填入的數字是否有效即可。
- 數字
1-9
在每一行只能出現一次。 - 數字
1-9
在每一列只能出現一次。 - 數字
1-9
在每一個以粗實線分隔的3x3
宮內只能出現一次。
image
<small style="box-sizing: border-box; font-size: 10.399999618530273px;">上圖是一個部分填充的有效的數獨。</small>
數獨部分空格內已填入了數字,空白格用 '.'
表示。
示例 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
形式的。
二、解題
直接遍歷二維數組,在第二個for循環里判斷每個元素,在其對應的行、列已經子數獨里驗證是否有重復數字即可。
先創建三個字典rowDict:[Int:[Character:Int]](存儲所有行的數字),columnDict: [Int:[Character:Int]](存儲所有列的數字),boxDict: [Int:[Character:Int]](存儲所有3x3子數獨中的數字)。
這里有個難點,就是子數獨的位置計算let bIndex = i / 3 * 3 + j / 3
。
詳細請看代碼:
時間復雜度:O(m*n)。(假設board[m][n])
三、代碼實現
class Solution {
func isValidSudoku(_ board: [[Character]]) -> Bool {
var rowDict: [Int:[Character:Int]] = [:]
var columnDict: [Int:[Character:Int]] = [:]
var boxDict: [Int:[Character:Int]] = [:]
for i in (0..<9) {
for j in (0..<9) {
let c = board[i][j]
if c == "." {
continue
}
if rowDict[i] == nil {
rowDict[i] = [:]
}
if rowDict[i]![c] != nil {
return false
}else{
rowDict[i]![c] = 1
}
if columnDict[j] == nil {
columnDict[j] = [:]
}
if columnDict[j]![c] != nil {
return false
}else{
columnDict[j]![c] = 1
}
let bIndex = i / 3 * 3 + j / 3
if boxDict[bIndex] == nil {
boxDict[bIndex] = [:]
}
if boxDict[bIndex]![c] != nil {
return false
}else {
boxDict[bIndex]![c] = 1
}
}
}
return true
}
}
Demo地址:github