持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第18天,点击查看活动详情
今天,我们继续搞算法。
题目描述
请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。
数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
注意:
一个有效的数独(部分已被填充)不一定是可解的。 只需要根据以上规则,验证已经填入的数字是否有效即可。 空白格用 '.' 表示。
题目分析
这个题目是让我们验证是不是数独,按照题目的规则来就行,先看行,行不能重复,我们一共看是9行,每行度是不一样的数组,每一行都是要不能重复的数字,所以我们需要9个这样的hashset,然后判断一下是否重复,不重复的话就加,我们需要取对应的hashset,那就需要一个映射map来维护每行和每列的hashSet的关系就好了,行列块都是这么判断。
问题是块的索引既不是i也不是j,那我们就需要计算,把二维索引先转换成块索引,再把块索引转换成对应的一维索引即可。
解题思路
- 确定操作对象:本题中,操作对象1个root,1个board
- 确定操作条件:把不是数的字符剪掉
- 确定操作过程:操作过程就是判断是否有重复数字。
- 确定结果返回:返回最终结果。
代码
class Solution {
public boolean isValidSudoku(char[][] board) {
HashMap<Integer, HashSet<Character>> rowMap = new HashMap<>(),
colMap = new HashMap<>(), boxMap = new HashMap<>();
for(int i=0;i<9;i++){
rowMap.put(i, new HashSet<>());
colMap.put(i, new HashSet<>());
boxMap.put(i, new HashSet<>());
}
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
char ch = board[i][j];
if (ch =='.') continue;
HashSet<Character> rowSet = rowMap.get(i);
if (rowSet.contains(ch)){
return false;
}else {
rowSet.add(ch);
}
HashSet<Character> colSet = colMap.get(j);
if (colSet.contains(ch)){
return false;
}else {
colSet.add(ch);
}
int boxIndex = (i / 3) * 3 + (j/3);
HashSet<Character> boxSet = boxMap.get(boxIndex);
if (boxSet.contains(ch)){
return false;
}else {
boxSet.add(ch);
}
}
}
return true;
}
}