[LeetCode] #36 有效的数独

 

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

数字 1-9 在每一行只能出现一次。

数字 1-9 在每一列只能出现一次。

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

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

注意:

一个有效的数独(部分已被填充)不一定是可解的。

只需要根据以上规则,验证已经填入的数字是否有效即可。

 

输入: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"]]
输出:true

使用哈希表

class Solution {
    public boolean isValidSudoku(char[][] board) {
        Set<Character> set1 = new HashSet<>();
        Set<Character> set2 = new HashSet<>();
        Set<Character> set3 = new HashSet<>();
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                if (board[j][i] != '.' && !set1.add(board[j][i]))
                    return false;
                if (board[i][j] != '.' && !set2.add(board[i][j]))
                    return false;
                    //(0,0)(0,1)(0,2)(1,0)(1,1)(1,2)(2,0)(2,1)(2,2)
                    //(0,3)(0,4)(0,5)(1,3)(1,4)(1,5)(2,3)(2,4)(2,5) 
                    //(0,6)(0,7)(0,8)(1,6)(1,7)(1,8)(2,6)(2,7)(2,8)
                    //(3,0)(3,1)(3,2)(4,0)(4,1)(4,2)(5,0)(5,1)(5,2)
                    //(3,3)(3,4)(3,5)(4,3)(4,4)(4,5)(5,3)(5,4)(5,5)
                    //(3,6)(3,7)(3,8)(4,6)(4,7)(4,8)(5,6)(5,7)(5,8)
                    //(6,0)(6,1)(6,2)(7,0)(7,1)(7,2)(8,0)(8,1)(8,2)
                    //(6,3)(6,4)(6,5)(7,3)(7,4)(7,5)(8,3)(8,4)(8,5)
                    //(6,6)(6,7)(6,8)(7,6)(7,7)(7,8)(8,6)(8,7)(8,8)
                if (board[i % 3 * 3 + j / 3][i / 3 * 3 + j % 3] != '.' 
                && !set3.add(board[i % 3 * 3 + j / 3][i / 3 * 3 + j % 3]))
                    return false;
            }
            set1.clear();
            set2.clear();
            set3.clear();
        }
        return true;
    }
}

使用数组代替哈希表

class Solution {
    public boolean isValidSudoku(char[][] board) {
        int[][] rows = new int[9][9];
        int[][] columns = new int[9][9];
        int[][][] subboxes = new int[3][3][9];
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                char c = board[i][j];
                if (c != '.') {
                    int index = c - '0' - 1;
                    rows[i][index]++;
                    columns[j][index]++;
                    subboxes[i / 3][j / 3][index]++;
                    if (rows[i][index] > 1 || columns[j][index] > 1 || subboxes[i / 3][j / 3][index] > 1) {
                        return false;
                    }
                }
            }
        }
        return true;
    }
}

或者

class Solution {
    public boolean isValidSudoku(char[][] board) {
        boolean[][] row = new boolean[9][9];
        boolean[][] col = new boolean[9][9];
        boolean[][] block = new boolean[9][9];

        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                if (board[i][j] != '.') {
                    int num = board[i][j] - '1';
                    int blockIndex = i / 3 * 3 + j / 3;
                    if (row[i][num] || col[j][num] || block[blockIndex][num]) {
                        return false;
                    } else {
                        row[i][num] = true;
                        col[j][num] = true;
                        block[blockIndex][num] = true;
                    }
                }
            }
        }
        return true;
    }
}

使用位运算代替哈希表

class Solution {
    public boolean isValidSudoku(char[][] board) {
        for (int i = 0; i < 9; i++) {
            int tmp = 0;
            int tmp2 = 0;
            for (int j = 0; j < 9; j++) {
                if (board[i][j] != '.') {
                    int t = tmp | (1 << (board[i][j] - '0'));
                    if (t == tmp) return false;
                    tmp = t;
                }
                if (board[j][i] != '.') {
                    int t = tmp2 | (1 << (board[j][i] - '0'));
                    if (t == tmp2) return false;
                    tmp2 = t;
                }
            }
        }
        for (int x = 0; x <= 6; x+=3) {
            for (int y = 0; y <= 6; y+=3) {
                int tmp = 0;
                for (int i = 0; i < 3; i++) {
                    for (int j = 0; j < 3; j++) {
                        if (board[i + x][j + y] != '.') {
                            int t = tmp | (1 << (board[i + x][j + y] - '0'));
                            if (t == tmp) return false;
                            tmp = t;
                        }
                    }
                }
            }
        }
        return true;
    }
}

知识点:

总结:

 

posted @ 2021-10-13 15:39  1243741754  阅读(29)  评论(0编辑  收藏  举报