leetcode_有效的数独_C++代码(附思路)

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

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

上图是一个部分填充的有效的数独。
数独部分空格内已填入了数字,空白格用'.'表示。

示例一:

输入:
[
  ["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

示例二:

输入:
[
  ["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"]
]
输出: false
解释: 除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与示例 1 相同。
     但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。

说明:

  • 一个有效的数独(部分已被填充)不一定是可解的。
  • 只需要根据以上规则,验证已经填入的数字是否有效即可。
  • 给定数独序列只包含数字1-9和字符'.'
  • 给定数独永远是9x9形式的。

思路:

因为有三个规则(每行,每列,每个3*3的子数独都不能出现一样的数字),而这三个规则都可以通过顺序遍历数独中每个数而进行判断(判断完可以分别用三个数组记录下来),且这三个规则互不干涉,所以通过一次顺序遍历就可以判断整个数独是否有效。

有个小的难点是怎么记录出现在3*3子数独中出现的数字。

肯定是要从这个表格中找到规律。
首先想到这九组3*3的子数独可以通过遍历(1,1)(1,4)这类中心位置进行发散判断,但是每组的中心块不连续,而且规律性很差。
这时我们想到,int类型的除法结果是向下取整的,而这九个子数独的行和列都是三个一循环。然后这除出来以后的两组(0,1,2)刚好可以组合成0到8连续的九个数。

代码实现

class Solution {
public:
    bool isValidSudoku(vector<vector<char>>& board) {
    //rule1[0][2]=1  第一行出现过数字3,一次。
    //rule2[2][0]=0 第一列出现过数字3,零次。
    //rule3[0][4]=2 第一组子数独中出现了5,两次。
        int rule1[10][10]={0},rule2[10][10]={0},rule3[10][10]={0};
        for(int row=0;row<9;row++)
        {
            for(int col=0;col<9;col++)
            {
                if(board[row][col]>='0'&&board[row][col]<='9')
                {
                    rule1[row][board[row][col]-'0']++;
                    if(rule1[row][board[row][col]-'0']>1)
                    return false;
                    rule2[board[row][col]-'0'][col]++;
                    if(rule2[board[row][col]-'0'][col]>1)
                    return false;
                    int name=row/3+(col/3)*3;
                    rule3[name][board[row][col]-'0']++;
                    if(rule3[name][board[row][col]-'0']>1)
                    return false;
                }
            }
        }
        return true;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值