LeetCode演算法題36:有效的數獨解析
阿新 • • 發佈:2019-01-03
判斷一個 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 形式的。
這個題就按標記檢視行、列、3*3單元格是否數字重複即可,遍歷整個表時遇到數字將對應標誌陣列的位置置為true,如果下次發現位置已經為true說明重複,返回false。行列的標誌很好置位,單元格的陣列置位可以這樣:一共九個單元格,其座標與陣列對應位置為
(0,0)(0,1)(0,2) (0,3)(0,4)(0,5) (0,6)(0,7)(0,8) (1,0)(1,1)(1,2)-->第0行 (1,3)(1,4)(1,5)-->第1行 (1,6)(1,7)(1,8)-->第2行 (2,0)(2,1)(2,2) (2,3)(2,4)(2,5) (2,6)(2,7)(2,8) (3,0)(3,1)(3,2) (3,3)(3,4)(3,5) (3,6)(3,7)(3,8) (4,0)(4,1)(4,2)-->第3行 (4,3)(4,4)(4,5)-->第4行 (4,6)(4,7)(4,8)-->第5行 (5,0)(5,1)(5,2) (5,3)(5,4)(5,5) (5,6)(5,7)(5,8) (6,0)(6,1)(6,2) (6,3)(6,4)(6,5) (6,6)(6,7)(6,8) (7,0)(7,1)(7,2)-->第8行 (7,3)(7,4)(7,5)-->第7行 (7,6)(7,7)(7,8)-->第8行 (8,0)(8,1)(8,2) (8,3)(8,4)(8,5) (8,6)(8,7)(8,8)
所以其對應關係可以描述為3*(i/3)+(j/3)。
C++原始碼:
class Solution {
public:
bool isValidSudoku(vector<vector<char>>& board) {
int m = board.size();
int n = board[0].size();
if (m!=9 || n!=9) return false;
vector<vector<bool>> row(m, vector<bool>(n, false));
vector<vector<bool>> col(m, vector<bool>(n, false));
vector<vector<bool>> cell(m, vector<bool>(n, false));
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
int t = board[i][j];
if(t>='1' && t<='9')
{
int k = t - '1';
if(row[i][k] || col[k][j] || cell[3*(i/3)+j/3][k])
return false;
row[i][k] = true;
col[k][j] = true;
cell[3*(i/3)+j/3][k] = true;
}
}
}
return true;
}
};
python3原始碼:
class Solution:
def isValidSudoku(self, board):
"""
:type board: List[List[str]]
:rtype: bool
"""
m = len(board)
n = len(board[0])
if m!=9 or n!=9:
return False
row = [[False for col in range(n)] for row in range(m)]
col = [[False for col in range(n)] for row in range(m)]
cell = [[False for col in range(n)] for row in range(m)]
for i in range(m):
for j in range(n):
t = ord(board[i][j])
if t>=ord('1') and t<=ord('9'):
k = t - ord('1')
if row[i][k] or col[k][j] or cell[3*(i//3)+(j//3)][k]:
return False
row[i][k] = True
col[k][j] = True
cell[3*(i//3)+(j//3)][k] = True
return True
這裡要注意的是python中list初始化的時候的程式碼,這種初始化是比較推薦的,如果使用[[false]*n]*m這種方式只是淺複製,會造成只要修改一個那麼每一行都會修改的問題。所以還是採用推薦的方法去初始化列表。