【LeetCode-哈希表】有效的数独
题目描述
判断一个 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
题目链接: https://leetcode-cn.com/problems/valid-sudoku/
思路
最自然的想法就是遍历数组 3 遍,每一遍判断行、列、3x3区域内(下面称为 box)是否有重复的数字。其实,可以在一次遍历中同时判断这 3 种情况。我们使用 3 个哈希表来记录每行、每列、每个 box 中元素的出现的情况。假设当前的位置是 (r, c),则通过行号 r 和列号 c 在对应的哈希表中判断当前元素 board[r][c] 是否出现,对于 box,我们将其编号如下
这样,box 的编号就等于 (r/3)*3+c/3。所以,我们可以在一次遍历中同时判断行、列、box 中的情况。
代码如下:
class Solution {
public:
bool isValidSudoku(vector<vector<char>>& board) {
if(board.empty()) return false;
vector<unordered_set<int>> rows(9);
vector<unordered_set<int>> cols(9);
vector<unordered_set<int>> box(9);
for(int i=0; i<9; i++){
for(int j=0; j<9; j++){
if(board[i][j]=='.') continue;
int num = board[i][j];
if(rows[i].count(num)!=0) return false;
if(cols[j].count(num)!=0) return false;
if(box[(i/3)*3+j/3].count(num)!=0) return false;
rows[i].insert(num);
cols[j].insert(num);
box[(i/3)*3+j/3].insert(num);
}
}
return true;
}
};
上面的代码用的是 unordered_set 来判断一个元素是否存在,也可以直接用数组。代码如下:
class Solution {
public:
bool isValidSudoku(vector<vector<char>>& board) {
if(board.empty()) return false;
vector<vector<bool>> rows(9, vector<bool>(9, false));
vector<vector<bool>> cols(9, vector<bool>(9, false));
vector<vector<bool>> box(9, vector<bool>(9, false));
for(int i=0; i<9; i++){
for(int j=0; j<9; j++){
if(board[i][j]=='.') continue;
int val = board[i][j]-'1';
if(!rows[i][val] && !cols[j][val] && !box[(i/3)*3+j/3][val]){
rows[i][val] = true;
cols[j][val] = true;
box[(i/3)*3+j/3][val] = true;
}else return false;
}
}
return true;
}
};
- 时间复杂度:O(1)
- 空间复杂度:O(1)
参考
https://leetcode-cn.com/problems/valid-sudoku/solution/you-xiao-de-shu-du-by-leetcode/