1

题目详情

Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules.
The Sudoku board could be partially filled, where empty cells are filled with the character '.'.

输入一个二维数组表示的数独版(board)。要求我们判断已经填入的数字是否满足数独的规则。即满足每一行、每一列、每一个粗线宫(3*3)内的数字均含1-9,不重复。没有数字的格子用字符'.'表示。

例如:
clipboard.png

想法

  • 这道题没有什么陷阱,主要的想法就是检查每一行现有的元素、每一列现有的元素、每一个粗线宫里的现有元素有没有重复。
  • 麻烦一点的解法就是我们用三次遍历分别检查每一行、每一列、每个粗线宫。但是这样代码比较复杂比较ugly,但是好理解呀~
  • 另一种简洁的想法把三种判断在一次遍历中完成。
  • 通过两层循环可以方便的检查每一行和每一列有没有重复数字。那我们如何遍历每个粗线宫呢?
  • 因为临时变量j的取值是从0-9,我们可以用'/'和'%'两个操作符来代替完成遍历粗线宫的行为。
  • j/3的值作为纵坐标的增量,j%3的值作为横坐标的增量。
  • 这样对于一个粗线宫的左上角顶点来说,j从0~9就可以完成对于整个粗线宫的遍历。
  • 然后我们仍需要确定每一个粗线宫的顶点。
  • 对于每个i,(i/3)3作为纵坐标,(i%3)3作为横坐标。这样对于i从0~9,我们可以取到每一个粗线宫的左上角了。

解法

  • 简洁版~
public boolean isValidSudoku(char[][] board) {
    for(int i = 0; i<9; i++){
        HashSet<Character> rows = new HashSet<Character>();
        HashSet<Character> columns = new HashSet<Character>();
        HashSet<Character> cube = new HashSet<Character>();
        for (int j = 0; j < 9;j++){
            if(board[i][j]!='.' && !rows.add(board[i][j]))
                return false;
            if(board[j][i]!='.' && !columns.add(board[j][i]))
                return false;
            int RowIndex = 3*(i/3);
            int ColIndex = 3*(i%3);
            if(board[RowIndex + j/3][ColIndex + j%3]!='.' && !cube.add(board[RowIndex + j/3][ColIndex + j%3]))
                return false;
        }
    }
    return true;
}
  • 复杂点~~
    public boolean isValidSudoku(char[][] board) {
        boolean res = true;
        int length = 9;
        
        //判断行
        for(int i=0;i<length;i++){
            HashSet<Character> temp = new HashSet<Character>();
            for(char c : board[i]){
                if(c != '.'){
                    if(!temp.add(c)){
                        return false;
                    }
                }
            }
        }
        
        //判断列
        for(int i=0;i<length;i++){
            HashSet<Character> temp = new HashSet<Character>();
            for(int j=0;j<length;j++){
                char c = board[j][i];
                if(c != '.'){
                    if(!temp.add(c)){
                        return false;
                    }
                }               
            }
        }
        
        //判断方块
        int[][] center = {{1,1},{1,4},{1,7},{4,1},{4,4},{4,7},{7,1},{7,4},{7,7}};
        int[][] directs = {{-1,-1},{-1,0},{1,0},{0,-1},{0,0},{0,1},{1,-1},{1,0},{1,1}};
        
        for(int[] a :center){
            HashSet<Character> temp = new HashSet<Character>();
            for(int[] direct : directs){
                char c =board[direct[0]+a[0]][direct[1]+a[1]];
                if(c != '.'){
                    if(!temp.add(c)){
                        return false;
                    }
                }  
            }
        }

        
        return res;
    }  

soleil阿璐
350 声望45 粉丝

stay real ~