面向小白的力扣36.有效的数独

118 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第18天,点击查看活动详情

今天,我们继续搞算法。

题目描述

请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。

数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)  

注意:

一个有效的数独(部分已被填充)不一定是可解的。 只需要根据以上规则,验证已经填入的数字是否有效即可。 空白格用 '.' 表示。

image.png

题目分析

这个题目是让我们验证是不是数独,按照题目的规则来就行,先看行,行不能重复,我们一共看是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;
    }
}