数独有效性校验

数独有效性校验

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

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

这里写图片描述

上图是一个部分填充的有效的数独。
以下输入是一个二维数组,部分元素已填入了数字,空白格用 ‘.’ 表示。
示例 1:
输入:
[
[“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

粗暴的检测思路:
1. 用一个大小为 9 的辅助的bool数组,对以上3种情况进行校验,分别校验每一行的数字不重复,每一列的数字不重复,每个3 * 3 的矩阵内数字不重复
2. 遍历每个数字,判断该数字所在行 和 所在列 和所在的 3 * 3 矩阵是否存在相同数字,存在则无效。

以下使用解法1 实现,其实都差不多,解法2 由于没有辅助数组,时间复杂度会更大。

//将辅助数组重新初始化
void resetExternArr(bool *m)
{
    for(int i=1; i< 10; i++)
        m[i]=false;
}

bool isValidSudoku(char** board, int boardRowSize, int boardColSize) 
{
   bool m[10] = {0,0,0,0,0,0,0,0,0,0}; //辅助数组
   //校验每一行的数是否重复
   for (int i=0; i < boardRowSize; i++)
   {
       for (int j=0; j< boardColSize; j++)
       {
           if (board[i][j]=='.')
               continue;
           //如果遍历到的数字已经存在了,则直接返回无效
           if (m[board[i][j]-'0']) 
               return false;
           //将遍历过的数字对应的 bool 值置为 true
           m[board[i][j]-'0'] = true; 
       }
       //每遍历完一行,要将辅助数组重置。
       resetExternArr(m);
   }
   //校验每一列的数是否重复,这里的循环与上面的循环都一样,只是访问的时候从 board[i][j] 变成了 board[j][i]
   for (int i=0; i < boardRowSize; i++)
   {
       for (int j=0; j < boardColSize; j++)
       {
           if (board[j][i]=='.')
               continue;
           if (m[board[j][i]-'0'])
               return false;
           m[board[j][i]-'0'] = true;
       }
       resetExternArr(m);
    }
    //校验每一个3 * 3 的矩阵是否有重复元素
    //最外层的两个 for 循环是对 3 * 3 的9个矩阵进行遍历
    for (int start = 0; start <=6; start+=3)
    {
        for (int end = 0; end <=6; end+=3)
        {
            //内层的两个 for 循环是遍历该矩阵的 9 个元素
            for (int i=start;i<start+3;i++)
            {
                for(int j=end; j<end+3;j++)
                {
                    if (board[i][j]=='.')
                        continue;
                    if (m[board[i][j]-'0'])
                        return false;
                    m[board[i][j]-'0'] = true;
                }
            }
            //判断完一个矩阵,将辅助数组重置
            resetExternArr(m);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/u011228889/article/details/80469238
今日推荐