LeetCode:有效的数独

题目描述

请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。

 

数字 1-9 在每一行只能出现一次。

数字 1-9 在每一列只能出现一次。

数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

作者:力扣 (LeetCode)

链接:https://leetcode-cn.com/leetbook/read/top-interview-questions-easy/x2f9gg/

来源:力扣(LeetCode)

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

题目解析

例,输入如下数据

输入:board =

[["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"]]

输出:true

  这个题目怎么去分析呢?首先它有9行,9列,9个小四方块,最简单的方法我们弄27个HashMap也能解决该问题,但它不是最优解。怎样才能找到最优解呢?先分拆问题,将问题简单化,解决简单问题找到规律后再解决原有问题。如果只有一行9个数字,我们怎么判断它是否有重复的呢?我们顺着前面那个暴力破解的思路来分析,当然我们可以使用HashMap来解决,但是组合问题后,解题方式又变成刚才的解法了。

    为了引出解题方法,我们先将一个故事,前些日子我陪女儿玩过一个这样的游戏:面前有7个杯子和七个球,杯子和球的颜色一一对应,需要把球放到相同颜色的杯子了。对这个游戏我们做一下延申,标有1-9的数字的杯子和标有1-9的数字的小球,将小球放到相同数字的杯子里,如果有很多小球呢?我们是不是能够快速的确定手里的小球有没有重复的呢?

    通过上面的游戏,我们可以想象到如果把数独里的数字当成Key存在HashMap中,如果把这个数字当成Index索引,作为数组的下标也可以解决这个问题,这样我们只需要三个9*9的二位数组即可。我们首先定义一个代表所有行的数组:row[9][9],用i表示哪一行,用数独里的字符表示j,如果原始数组中存在i上不等于'.'的数字num,那么将num放着i行的num列,这里我们将row[i][num]置为1,代表这个行列已经存在值了。同理,我们定义colunm[9][9] ,用j表示第几列,赋值给该数组的行下标,num的处理同row。

  接下来我们定义9个区块的数组:block[9][9],首先,我们用block的每一行放置每一小块的原始元素,其次,我们要确认原始数组的那个元素属于哪一行block。通过分析可以得到index=i/3+j/3*3,index表示block那一行

  最后我们需要注意一点,原始数组的元素为char类型,因此我们想要得到对应的int类型的数字需要进行acsii转换num=char-'0'-1;我们用原始元素-1,是为了将元素转为数字下标,这样处理不应用验证重复的逻辑

题目解答

算法1,时间复杂度为 o(n²),直接上代码如下: 

int row[9][9];
        int colunm[9][9];
        int block[9][9];
    bool isValidSudoku(vector<vector<char>>& board) {
        
       for(int i=0;i<9;i++)
       {
           for(int j=0;j<9;j++)
           {
               if(board[i][j]=='.')
               {
                   continue;
               }
               int num=board[i][j]-'0'-1;
               int bindex=i/3+j/3*3;
                if(row[i][num]!=0 || colunm[j][num]!=0 || block[bindex][num]!=0)
               {
                   return false;
               }
               row[i][num]=colunm[j][num]=block[bindex][num]=1;
              
           }
       }
       return true;
    }

解题思路:解题思路再题目分析中已经详细阐明,此次不再累述。

posted @ 2021-12-09 18:16  杨凯2020  阅读(128)  评论(0编辑  收藏  举报