LeetCode:36. Valid Sudoku,数独是否有效 :

LeetCode:36. Valid Sudoku,数独是否有效 :

题目:

LeetCode:36. Valid Sudoku

描述:
Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules.
The Sudoku board could be partially filled, where empty cells are filled with the character ‘.’.
数独
A partially filled sudoku which is valid.
分析:
  • 判断一个数独是否有效的判断条件有三个:行、列、子格里都没有重复的1-9数字
    思路如下:
    1、遍历所有的数组元素,对其中数据进行如下操作:
    2、遇到空格也就是“.”时,判断是有效的,并且在定义数组的对应位置上设置其为1,表示已查到该项;
    3、首次遇到某数字时,首先设置其在数组中的位置为1,判定有效;
    4、当且仅当遇到重复数字时,判定无效。
    所以程序应该分为两部分,一部分编写遍历算法,将元素进行三种方式的比对。另一部分用来编写检验是否有效。
    5、细节实现
    1)遍历算法:
    (1)遍历数组元素board[i][j],判断三个条件:
    (2)遍历元素对应逻辑九宫格位置:
    anRow[j] = board[i][j],
    anCloum[i][j] = board[i][j],
    anSonSudoKu[j / 3 * 3 + i / 3][j % 3 * 3 + i % 3] = board[i][j]
    2) 检验有效( 在逻辑九宫格中标识状态位,1位已查询到):
    (1)首次遇到某数字时,首先设置其在数组中的位置为1,判定有效
    (2)当且仅当遇到重复数字时,判定无效
    (3)首次遇到某数字时,首先设置其在数组中的位置为1,判定有效;
代码:
bool checkValid(int anArr[], int nVal)
{
    // 2) 检验有效:
    //(1)首次遇到某数字时,首先设置其在数组中的位置为1,判定有效
    //(2)当且仅当遇到重复数字时,判定无效
    // (3) 遇到空格也就是“.”时,判断是有效的,并且在定义数组的对应位置上设置其为1,表示已查到该项;
    if (nVal < 0) // 判断(3) “.”情况
    {
        return true;
    }
    if (1 == anArr[nVal - 1]) // 判断(2) 重复数字情况
    {
        return false;
    }
    //(1) 首次遇到某数字
    anArr[nVal - 1] = 1;
    return true;
}

bool isValidSudoku(const vector<vector<char>>& board)
{
    // 1)遍历数组
    int anRow[9] = { 0 }; // 用于存储一行的元素比对结果
    int anCloum[9] = { 0 }; // 用于存储一列中的元素比对结果
    int anSonSudoKu[9] = { 0 }; // 用于存储子格的元素比对

    for (int i = 0; i < 9; i++)
    {
        memset(anRow, 0, sizeof(anRow));
        memset(anCloum, 0, sizeof(anCloum));
        memset(anSonSudoKu, 0, sizeof(anSonSudoKu));
        for (int j = 0; j < 9; j++)
        {
            if (!checkValid(anRow, board[i][j] - '0') // 检查第i行(0开始计数)
                || checkValid(anCloum, board[j][i] - '0') // 检查第j行(实际为第j列,0开始)
                || checkValid(anSonSudoKu, board[i / 3 * 3 + j / 3][i % 3 * 3 + j % 3] - '0') 
                // 检查 board[i][j] 元素所在 i / 3 * 3 所在行的3个九宫格的三个元素
                )
            {
                return false;
            }
        }
    }
    return true;
}

备注:
好记性不如烂笔头!这道题思考了好几天,才发现人和人差距是很大的~
借鉴了tenos大神的解法LeetCode:Valid Sudoku,Sudoku Solver(数独游戏)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值