力扣第三十六题-有效的数独

585 阅读3分钟

这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战

前言

力扣第三十六题 有效的数独 如下所示:

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

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

数独部分空格内已填入了数字,空白格用 '.' 表示。

注意:

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

 

示例 1:

image.png

一、思路

题目虽然很长,但如果你知道 数独 的话,那理解起来不会太困难。大致的意思就是:9x9 的方格中,每一行、每一列以及每一个 3x3 的方格中数字 1~9 都只能出现一次。根据规则校验数独是否有效

实现的大致实现也是挺简单的,思路就是一次遍历,校验三次

那么如何做到一次遍历,校验行、列以及 3x3 方格呢?

举个例子

我们可以使用三个数组来分别存储行、列以及 3x3 方格中相应数字出现的位置。

如下图所示,这是一个 9x9 的格子:

image.png

假设数字 8 在方格中的位置如下所示:

image.png

很明显数字 8第二行第二列3x3 的小方格中的位置为第 5 个位置,所以具体的存储如下:

int[][] rowRecords = new int[9][9]:行记录
int[][] colRecords = new int[9][9]:列记录
int[][] subBoxRecords = new int[9][9]:子盒子记录
tips:都是用二维数组是为了存储所有的行列及子盒子记录

rowRecords[1][7] = 1,第二行的第八个数字已存在
colRecords[1][7] = 1,第二列的第七个数字已存在
subBoxRecords[0][7] = 1,第一个子盒子的第七个数字已存在

所以只需要给三个数组赋值前,校验值是否已存在即可。如果已存在则直接返回false,说明该数独不合法。

二、实现

实现代码

public boolean isValidSudoku(char[][] board) {
    // 行记录
    int[][] rowRecords = new int[9][9];
    // 列记录
    int[][] colRecords = new int[9][9];
    // 子盒子记录
    int[][] subBoxRecords = new int[9][9];
    // 一次循环,校验3次
    for (int i=0; i<9; i++) {
        for (int j=0; j<9; j++) {
            char c = board[i][j];
            if (c == '.')
                continue;
            // 子盒子下标
            int boxIndex = i/3 + j/3*3;
            // 校验
            int val =  Integer.parseInt(String.valueOf(c)) - 1;
            boolean rowIncluded = rowRecords[i][val] == 1;
            boolean colIncluded = colRecords[j][val] == 1;
            boolean subBoxIncluded = subBoxRecords[boxIndex][val] == 1;
            if (rowIncluded || colIncluded || subBoxIncluded)
                return false;
            // 赋值
            rowRecords[i][val] = 1;
            colRecords[j][val] = 1;
            subBoxRecords[boxIndex][val] = 1;
        }
    }
    return true;
}

测试代码

public static void main(String[] args) {
    char[][] board = 
            {{'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'}};
    new Number36().isValidSudoku(board);
    
}

结果

image.png

三、总结

感谢看到最后,非常荣幸能够帮助到你~♥