[LeetCode] 36. 有效的數獨
阿新 • • 發佈:2019-05-09
square 復雜度 部分 dig 更多 填充 數字 一個 因此 ,
題目鏈接: https://leetcode-cn.com/problems/valid-sudoku/
題目描述:
判斷一個 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
形式的。
思路:
首先還是理清題意,就是每一行,每一列,每一個小正方形都不能重復出現一個字母,如下圖所示:
所以我們最直接想到就是,就是記錄它的行,列,和小正方形的值,有重復就false
思路一:
我們用一個字典,分別記錄行,列,和小正方形!
行,列我們直接可以用數字表示,小正方形如何表示呢?
這裏,我們發現一個規律,我們可以把小正方形變成用二維數組唯一標識,比如(0,0)
表示左上角那個,(1,1)
表示中間那個,他們和行列的關系就是(i//3,j//3)
所以任何位置我們都能找出它在哪個行,哪個列,哪個正方形裏!
時間復雜度都是常數級的
思路二:
上面我們用的空間復雜度有點多,要想辦法改進空間復雜度,
我們有點小技巧,我們只需要用一個集合就可以搞定!
比如我們把board[i][j]
用字符串:
表示行:(i)
+ board[i][j]
表示列: board[i][j]
+ (j)
表示小正方形:(i)
+ board[i][j]
+ (j)
就直接可以用一個集合搞定!
關註我的知乎專欄,了解更多的解題技巧,大家共同進步!
代碼:
思路一
class Solution:
def isValidSudoku(self, board: List[List[str]]) -> bool:
from collections import defaultdict
row = defaultdict(set)
col = defaultdict(set)
small_square = defaultdict(set)
for i in range(9):
for j in range(9):
if board[i][j].isdigit():
if board[i][j] not in row[i] and board[i][j] not in col[j] and board[i][j] not in small_square[(i // 3,j // 3)]:
row[i].add(board[i][j])
col[j].add(board[i][j])
small_square[(i // 3, j // 3)].add(board[i][j])
else:
return False
return True
思路二
python
class Solution:
def isValidSudoku(self, board: List[List[str]]) -> bool:
one_set = set()
for i in range(9):
for j in range(9):
if board[i][j].isdigit():
row = "(" + str(i) + ")" + board[i][j]
col = board[i][j] + "(" + str(j) + ")"
small_square = "(" + str(i//3)+ ")" + board[i][j] + "(" + str(j//3) + ")"
if row in one_set or col in one_set or small_square in one_set:
return False
one_set.update([row,col,small_square])
return True
java
class Solution {
public boolean isValidSudoku(char[][] board) {
Set<String> one_set = new HashSet<>();
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (board[i][j] != '.') {
String row = "(" + i + ")" + board[i][j];
String col = board[i][j] + "(" + j + ")";
String small_square = "(" + i / 3 + ")" + board[i][j] + "(" + j / 3 + ")";
if (!one_set.add(row) || !one_set.add(col) || !one_set.add(small_square)) return false;
}
}
}
return true;
}
}
[LeetCode] 36. 有效的數獨