36. Valid Sudoku




Determine if a 9x9 Sudoku board is valid. Only the filled cells need to be validated according to the following rules:
1. Each row must contain the digits 1-9 without repetition.
2. Each column must contain the digits 1-9 without repetition.
3. Each of the 9 3x3 sub-boxes of the grid must contain the digits 1-9 without repetition.


A partially filled sudoku which is valid.
The Sudoku board could be partially filled, where empty cells are filled with the character '.'.
Example 1:
Input:
[
  ["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"]
]
Output: true




Solution 2 : 

refactored code 
Remove redundancy 

https://leetcode.com/problems/valid-sudoku/discuss/15634/Sharing-my-easy-understand-java-solution-using-set



class Solution {
    public boolean isValidSudoku(char[][] board) {
        // we want to use the same helper function to do the valid check for every row, every col, and every 3 * 3 block 
        // what every row, every col, and every 3 * 3 block have in common is that they are all rectangles, in order to define 
        // a rectangle, we need two coordinates in the diagonal line of this rectangle 
        for(int i = 0; i < 9; i++){
            // check every row
            if(!valid(board, i, 0, i, 8)) return false;
            // check every col
            if(!valid(board, 0, i, 8, i)) return false;
        }
        // check every 3 * 3 block 
        for(int i = 0; i < 3; i++){
            for(int j = 0; j < 3; j++){
                int x1 = 3 * i;
                int y1 = 3 * j;
                int x2 = x1 + 2;
                int y2 = y1 + 2;
                if(!valid(board, x1, y1, x2, y2)) return false;
            }
        }
        return true;   
    }
    private boolean valid(char[][] board, int x1, int y1, int x2, int y2){
        Set visited = new HashSet<>();
        for(int i = x1; i <= x2; i++){
            for(int j = y1; j <= y2; j++){
                if(board[i][j] != '.'){
                    // set.add, it will add the element first if it's addable, but 
                    // return false if the element can't be added 
                    if(!visited.add(board[i][j])) return false;
                }
            }
        }
        return true;
    }
}


The tricky part is that we need to get all the common parameters for the helper function. 
For the block index, get common row index and common col index , from examples 
And summarize it into code in more general cases 






Solution 1 : brute force 

https://www.youtube.com/watch?v=iqe1JSjyldo






class Solution {
    public boolean isValidSudoku(char[][] board) {
        
        // check each row using a hashset , check each col using a hashes 
        //Check each 3 * 3 black using hashset 
        // check every row 
        // check every col 
        // check every 3 * 3 block 
        // correct corrdinates 
        
        if(!checkRow(board)) return false;
        if(!checkCol(board)) return false;
        if(!checkBlock(board)) return false;
        return true;
    }    
    private boolean checkRow(char[][] board){
        
        // row is from 0 to board.length, col is from 0 to board[0].length 
        for(int i = 0; i < board.length; i++){
            HashSet<Character> set = new HashSet<>();
            for(int j = 0; j < board[0].length; j++){
                if(!set.add(board[i][j])) return false;
            }
        }
        return true;
    }
    
    private boolean checkCol(char[][] board){
        // reverse order of checkRow 
        for(int i = 0; i < board[0].length; i++){
            HashSet<Character> set = new HashSet<>();
            for(int j = 0; j < board.length; j++){
                if(!set.add(board[i][j])) return false;
            }
        }
        return true;
    }
    
    private boolean checkBlock(char[][] board){
        // get start point for every 3 * 3 block, level by level 
        for(int i = 0; i < 3; i++){
            for(int j = 0; j < 3; j++){
                int row = 3 * i;
                int col = 3 * j;
                HashSet<Character> set = new HashSet<>();
                // now we have the start point coordinates, now we can check every block 
                for(int r = row; r < row + 3; r++){
                    for(int c = col; c < col + 3; c++){
                        if(!set.add(board[r][c])) return false;
                    }
                }
            }
        }
        return true;    
    }
}

 

posted on 2018-11-08 17:08  猪猪&#128055;  阅读(107)  评论(0)    收藏  举报

导航