LeetCode-36. Valid Sudoku

Posted 番茄汁汁

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode-36. Valid Sudoku相关的知识,希望对你有一定的参考价值。

一、问题描述

  判断一个不完整的数独是否正确。

  判断数独是否正确的条件:1、每行的数不重复。2、没列的数不重复。3、划分成的9个3*3的块中没有数重复。

  例子看下面代码中的测试用例。

二、问题解决

  思路一:分3次循环来解决,第一次横向遍历,第二次纵向遍历,第三次以块遍历。每一次遍历一行、一列、或是一块的时候使用map记录每个数出现的次数,当出现两次的时候返回false

bool isValidSudoku(vector<vector<char>>& board) {
    for (auto i : board) {
        map<char, int> map = { { 1,0 },{ 2,0 },{ 3,0 },{ 4,0 },
        { 5,0 },{ 6,0 },{ 7,0 },{ 8,0 },{ 9,0 }, };
        for (auto j : i) {
            if (j == .) continue;
            if (map[j] == 0)
                map[j]++;
            else
                return false;
        }
        map = { { 1,0 },{ 2,0 },{ 3,0 },{ 4,0 },
        { 5,0 },{ 6,0 },{ 7,0 },{ 8,0 },{ 9,0 }, };
    }

    for (int i = 0; i < 9; i++) {
        map<char, int> map = { { 1,0 },{ 2,0 },{ 3,0 },{ 4,0 },
        { 5,0 },{ 6,0 },{ 7,0 },{ 8,0 },{ 9,0 }, };
        for (int j = 0; j < 9; j++) {
            if (board[j][i] == .) continue;
            if (map[board[j][i]] == 0)
                map[board[j][i]]++;
            else
                return false;
        }
        map = { { 1,0 },{ 2,0 },{ 3,0 },{ 4,0 },
        { 5,0 },{ 6,0 },{ 7,0 },{ 8,0 },{ 9,0 }, };
    }

    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            map<char, int> map = { { 1,0 },{ 2,0 },{ 3,0 },{ 4,0 },
            { 5,0 },{ 6,0 },{ 7,0 },{ 8,0 },{ 9,0 }, };
            for (int m = 0; m < 3; m++) {
                for (int n = 0; n < 3; n++) {
                    int posx = m + i * 3;
                    int posy = n + j * 3;
                    if (board[posx][posy] == .) continue;
                    if (map[board[posx][posy]] == 0)
                        map[board[posx][posy]]++;
                    else
                        return false;
                }
            }
            map = { { 1,0 },{ 2,0 },{ 3,0 },{ 4,0 },
            { 5,0 },{ 6,0 },{ 7,0 },{ 8,0 },{ 9,0 }, };
        }
    }
    return true;
}

int main()
{
    vector<vector<char>> v = {{., ., ., ., 5, ., ., 1,.},
                            { ., 4, ., 3, ., ., ., ., . },
                            { ., ., ., ., ., 3, ., ., 1 },
                            { 8, ., ., ., ., ., ., 2, . },
                            { ., ., 2, ., 7, ., ., ., . },
                            { ., 1, 5, ., ., ., ., ., . },
                            { ., ., ., ., ., 2, ., ., . },
                            { ., 2, ., 9, ., ., ., ., . },
                            { ., ., 4, ., ., ., ., ., . } };
    cout << isValidSudoku(v) << endl;

    system("pause");
    return 0;
}

  思路二:更简洁方便的解决

bool isValidSudoku(vector<vector<char> > &board)
    {
        int used1[9][9] = {0}, used2[9][9] = {0}, used3[9][9] = {0};
        
        for(int i = 0; i < board.size(); ++ i)
            for(int j = 0; j < board[i].size(); ++ j)
                if(board[i][j] != .)
                {
                    int num = board[i][j] - 0 - 1, k = i / 3 * 3 + j / 3;
                    if(used1[i][num] || used2[j][num] || used3[k][num])
                        return false;
                    used1[i][num] = used2[j][num] = used3[k][num] = 1;
                }
        
        return true;
    }

三、问题总结

  在判断是否出现重复的时候使用9*9的数组来表示,而不是使用map。

  遍历一遍就ok了。

  在利用i和j计算块内索引的时候很巧妙,记住这种方法。

  大神的代码就是厉害。

以上是关于LeetCode-36. Valid Sudoku的主要内容,如果未能解决你的问题,请参考以下文章

leetcode36. Valid Sudoku

LeetCode 36. Valid Sudoku

LeetCode36. Valid Sudoku

leetcode36. Valid Sudoku

LeetCode 36 Valid Sudoku(合法的数独)

leetcode 36. Valid Sudoku