zoukankan      html  css  js  c++  java
  • [LeetCode] 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
    

    Example 2:

    Input:
    [
      ["8","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: false
    Explanation: Same as Example 1, except with the 5 in the top left corner being 
        modified to 8. Since there are two 8's in the top left 3x3 sub-box, it is invalid.
    

    Note:

    • A Sudoku board (partially filled) could be valid but is not necessarily solvable.
    • Only the filled cells need to be validated according to the mentioned rules.
    • The given board contain only digits 1-9 and the character '.'.
    • The given board size is always 9x9.

    数独 是一种逻辑性的数字填充游戏,玩家须以数字填进每一格,而每行、每列和每个宫(即3x3的大格)有齐1至9所有数字。游戏设计者会提供一部分的数字,使谜题只有一个答案。

    题目要求验证一个方阵是否为数独,判断标准是看各行各列是否有重复数字,以及每个小的3x3的小方阵里面是否有重复数字,如果都无重复,则当前矩阵是数独。但不代表该数独有解,只是判断当前未填完的矩阵是否是数独。

    解法:遍历方阵中的每个数字,检查包含当前位置的行和列以及3x3小方阵中是否已经出现该数字,需要分别记录行,列,小方阵是否出现该数字。

    Java:

    public class Solution {
        static int position[]=new int[]{2,4,8,16,32,64,128,256,512};
        /**
         * 分别判断行 列 和 格子内的就可以了~~~
         * 这里我使用的位运算来降低内存。。都是2的n次,那么对应的位置上直接使用位运算就能判断了
         * */
        public boolean isValidSudoku(char[][] board) {
            int col[]=new int[9];
            int row[]=new int[9];
            int zone[]=new int[9];
            int i,j,mask,qid;
            for(i=0;i<9;i++){
                for(j=0;j<9;j++){
                    if(board[i][j]=='.')
                        continue;
                    mask=position[board[i][j]-'1'];
                    qid=(i/3)*3+j/3;
                    if( (col[j] | mask) == col[j] || (row[i] | mask) == row[i] ||(zone[qid] | mask) == zone[qid])
                        return false;
                    col[j]=col[j]|mask;
                    row[i]=row[i]|mask;
                    zone[qid]=zone[qid]|mask;
                }
            }
            return true;
    
        }
    }  

    Java:

    public class Solution {  
        //置为静态变量  
        static Map<Character,Integer> map = new HashMap<Character,Integer>();  
        public boolean isValidSudoku(char[][] board) {  
            //判断每行  
            for(int i = 0; i < board.length; i++){  
                initMap();//每次均需初始化  
                for(int j = 0; j < board[0].length; j++){  
                    //是数字  
                    if(board[i][j] >= '0' && board[i][j] <= '9'){  
                        if(map.get(board[i][j]) > 0){//说明重复数字  
                            return false;  
                        }else{  
                            map.put(board[i][j],1);  
                        }  
                    }else if(board[i][j] != '.'){//出现空格和0-9之外的字符  
                        return false;//直接返回false  
                    }  
                }  
            }  
            //判断每列  
            for(int i = 0; i < board[0].length; i++){  
                initMap();//每次均需初始化  
                for(int j = 0; j < board.length; j++){  
                    //是数字  
                    if(board[j][i] >= '0' && board[j][i] <= '9'){  
                        if(map.get(board[j][i]) > 0){//说明重复数字  
                            return false;  
                        }else{  
                            map.put(board[j][i],1);  
                        }  
                    }else if(board[j][i] != '.'){//出现空格和0-9之外的字符  
                        return false;//直接返回false  
                    }  
                }  
            }  
            //判断九宫格  
            for(int i = 0; i < board.length - 2; i = i+3){//行{  
                for(int j = 0; j < board[0].length - 2; j=j+3){  
                    initMap();//初始化  
                    for(int m = i; m < i + 3;m++){  
                        for(int n = j; n < j+3; n++){  
                            //是数字  
                            if(board[m][n] >= '0' && board[m][n] <= '9'){  
                                if(map.get(board[m][n]) > 0){//说明重复数字  
                                    return false;  
                                }else{  
                                    map.put(board[m][n],1);  
                                }  
                            }else if(board[m][n] != '.'){//出现空格和0-9之外的字符  
                                return false;//直接返回false  
                            }  
                        }  
                    }  
                }  
            }  
            return true;  
        }  
        //初始化map为每个key均赋值0  
        private void initMap(){  
            for(char i = '0';i <= '9'; i++){  
                map.put(i,0);  
            }  
        }  
    }  
    

    Python:

    class Solution(object):
        def isValidSudoku(self, board):
            """
            :type board: List[List[str]]
            :rtype: bool
            """
            for i in xrange(9):
                if not self.isValidList([board[i][j] for j in xrange(9)]) or 
                   not self.isValidList([board[j][i] for j in xrange(9)]):
                    return False
            for i in xrange(3):
                for j in xrange(3):
                    if not self.isValidList([board[m][n] for n in xrange(3 * j, 3 * j + 3) 
                                                         for m in xrange(3 * i, 3 * i + 3)]):
                        return False
            return True
        
        def isValidList(self, xs):
            xs = filter(lambda x: x != '.', xs)
            return len(set(xs)) == len(xs)
    

    C++:

    class Solution {
    public:
        bool isValidSudoku(vector<vector<char> > &board) {
            if (board.empty() || board[0].empty()) return false;
            int m = board.size(), n = board[0].size();
            vector<vector<bool> > rowFlag(m, vector<bool>(n, false));
            vector<vector<bool> > colFlag(m, vector<bool>(n, false));
            vector<vector<bool> > cellFlag(m, vector<bool>(n, false));
            for (int i = 0; i < m; ++i) {
                for (int j = 0; j < n; ++j) {
                    if (board[i][j] >= '1' && board[i][j] <= '9') {
                        int c = board[i][j] - '1';
                        if (rowFlag[i][c] || colFlag[c][j] || cellFlag[3 * (i / 3) + j / 3][c]) return false;
                        rowFlag[i][c] = true;
                        colFlag[c][j] = true;
                        cellFlag[3 * (i / 3) + j / 3][c] = true;
                    }
                }
            }
            return true;
        }
    };
    

    All LeetCode Questions List 题目汇总

      

  • 相关阅读:
    分享一份Java架构师学习资料,2019年最新整理!
    Spring Boot 最核心的 25 个注解,都是干货!
    推荐一款接口 API 设计神器!
    题库
    杂乱的知识点
    mysql查询疯狂41例
    mysql你问我答
    可能出现的面试题
    SQLALchemy
    基于蓝图的完整的Flask项目
  • 原文地址:https://www.cnblogs.com/lightwindy/p/8556469.html
Copyright © 2011-2022 走看看