36. Valid Sudoku [Medium]

自己不会做,看的discuss

HashSet判断元素相等是用equals()方法

【本题要点】

1.1 用hashset判断元素重复(若add重复元素会返回false

1.2 用boolean类型的二维数组标识元素是否出现过,默认初始值为false,出现则改为true,达到识别重复的效果

2. 判断元素属于哪一个九宫格(用(i / 3) * 3 + j / 3唯一标识第0~8的9个九宫格)

/**
 * 用一个9*9的循环,扫描每一行、每一列、每一个九宫格
 * 为每一行、列、九宫格建立一个hashset,向hashset中add扫描到的元素
 * 当任意hashset的add得到false的返回结果,就return false
 * 如果程序进行到扫描完成,则return true
 * Runtime: 7 ms, faster than 28.17%
 * Memory Usage: 44.1 MB, less than 5.00%
 */
class Solution {
    public boolean isValidSudoku(char[][] board) {
        for (int i = 0; i < 9; i++) {
            HashSet<Character> row = new HashSet<>(); // 扫描第i行
            HashSet<Character> col = new HashSet<>(); // 扫描第i列
            HashSet<Character> cube = new HashSet<>(); // 扫描第i个cube
            int top = (i / 3) * 3, left = (i % 3) * 3; // 第i个cube左上角的横纵坐标
            for (int j = 0; j < 9; j++) {  
                if (board[i][j] != '.' && !row.add(board[i][j])) // 第i行出现重复元素
                    return false;
                if (board[j][i] != '.' && !col.add(board[j][i])) // 第i列出现重复元素
                    return false;
                char cubElement = board[top + j / 3][left + j % 3]; 
                if (cubElement != '.' && !cube.add(cubElement)) // 第i个cube出现重复元素
                    return false;
            }
        }
        return true;
    }
}
/**
 * 该方法只需要用一个字符串类型的hashset
 * 如下代码中将每一行的元素表示为“[元素值]row[行数]”的字符串,每一列的元素表示为“[元素值]col[列数]”,每一九宫格的元素表示为“[元素值]cube[cube数]”((i/3)*3+j/3能唯一标识0~9个九宫格)
 * 遍历每个单元格,将元素的每一行、每一列、每一九宫格的字符串add进hashset
 * 如果出现add失败,说明在行或列或cube中出现了重复的数字,即return false
 * 遍历完仍未返回,则return true
 * Runtime: 11 ms, faster than 25.58%
 * Memory Usage: 39.5 MB, less than 23.73%
 */
class Solution {
    public boolean isValidSudoku(char[][] board) {
        HashSet<String> set = new HashSet<>();
        for (int i = 0; i < 9; i++)
            for (int j = 0; j < 9; j++)
                if (board[i][j] != '.' && (!set.add(board[i][j] + "row" + i) || !set.add(board[i][j] + "col" + j) || !set.add(board[i][j] + "cube" + ((i / 3) * 3 + j / 3))))
                        return false;
        return true;
    }
}
/**
 * 题目要求9个行、9个列、9个九宫格,各自不能有重复的元素
 * 用三维数组matrix[3][9][9]存储,matrix[i][j][k]中
 * i代表类型,1是行2是列3是九宫格;j代表第j个(第j行or第j列or第j个九宫格);k代表具体元素值
 * 例如matrix[0][1][2]的值表示第2行(索引为1)是否出现过数字3(索引为2)
 * 对于每一个元素board[i][j],它占用的位置即矩阵中k的值,为curr = board[i][j] - '1'(要转字符类型为int,且矩阵index从0开始)
 * 它会占用所在行、列、九宫格的各一个元素,分别为matrix[0][i][curr]、matrix[1][j][curr]、matrix[2][i / 3 * 3 + j / 3][curr]
 * 检查这几个位置如果已经被标为true,说明这个元素在行or列or九宫格中造成了重复,则return false
 * 如果遍历完整个矩阵都没有返回,则return true
 * Runtime: 1 ms, faster than 100.00%
 * Memory Usage: 38.8 MB, less than 78.52%
 */
class Solution {
    public boolean isValidSudoku(char[][] board) {
        boolean[][][] matrix = new boolean[3][9][9];
        for (int i = 0; i < 9; i++)
            for (int j = 0; j < 9; j++)
                if (board[i][j] != '.') {
                    int curr = board[i][j] - '1', cubeIdx = i / 3 * 3 + j / 3;
                    if (matrix[0][i][curr] || matrix[1][j][curr] || matrix[2][cubeIdx][curr])
                        return false;
                    matrix[0][i][curr] = true;
                    matrix[1][j][curr] = true;
                    matrix[2][cubeIdx][curr] = true;
                }   
        return true;
    }
}
/**
 * 和上面的代码思路相同,只是把三维数组拆成了3个二维数组
 * 将行、列、九宫格中出现的元素情况分别用一个二维数组记录
 * Runtime: 1 ms, faster than 100.00%
 * Memory Usage: 38.8 MB, less than 78.52%
 */
class Solution {
    public boolean isValidSudoku(char[][] board) {
        boolean[][] row = new boolean[9][9]; // 记录所有行中出现的元素情况,9行,每一行可能有1-9的9个值
        boolean[][] col = new boolean[9][9]; // 记录所有列中出现的元素情况,9列,每一列可能有1-9的9个值
        boolean[][] cube = new boolean[9][9]; // 记录所有九宫格中出现的元素情况,9个九宫格,每一九宫格可能有1-9的9个值
        for (int i = 0; i < 9; i++)
            for (int j = 0; j < 9; j++)
                if (board[i][j] != '.') {
                    int valIdx = board[i][j] - '1', cubeNo = i / 3 * 3 + j / 3;
                    if (row[i][valIdx] || col[j][valIdx] || cube[cubeNo][valIdx])
                        return false;
                    row[i][valIdx] = true;
                    col[j][valIdx] = true;
                    cube[cubeNo][valIdx] = true;
                }
        return true;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值