「力扣」上的两道数独问题(草稿,不要看)

261 阅读1分钟

「力扣」第 36 题:

public class Solution {

    public boolean isValidSudoku(char[][] board) {
        boolean[][] row = new boolean[9][10];
        boolean[][] col = new boolean[9][10];
        boolean[][][] cell = new boolean[3][3][10];

        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                // 注意 1:'.' 的时候跳过
                if (board[i][j] == '.') {
                    continue;
                }

                // 注意 2:这里转换成整型数值
                int num = board[i][j] - '0';
                
                // 注意 3:cell[i / 3][j / 3] 下标的变化
                if (row[i][num] || col[j][num] || cell[i / 3][j / 3][num]) {
                    return false;
                }
                row[i][num] = true;
                col[j][num] = true;
                cell[i / 3][j / 3][num] = true;
            }
        }
        return true;
    }
}

因为「状态」只有 9 个,把布尔数组集中到 1 个数上,这种技巧叫做「状态压缩」。

public class Solution2 {

    public boolean isValidSudoku(char[][] board) {
        int[] row = new int[9];
        int[] col = new int[9];
        int[][] cell = new int[3][3];

        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                // 注意 1:'.' 的时候跳过
                if (board[i][j] == '.') {
                    continue;
                }

                // 注意 2:这里转换成整型数值,这里转换成整型数值 0 - 8
                int num = board[i][j] - '1';

                // 注意 3:cell[i / 3][j / 3] 下标的变化
                boolean rowExists = ((row[i] >> num) & 1) == 1;
                boolean colExists = ((col[j] >> num) & 1) == 1;
                boolean cellExists = ((cell[i / 3][j / 3] >> num) & 1) == 1;


                if (rowExists || colExists || cellExists) {
                    return false;
                }
                row[i] ^= 1 << num;
                col[j] ^= 1 << num;
                cell[i / 3][j / 3] ^= 1 << num;
            }
        }
        return true;
    }
}

「力扣」第 37 题: