36. 有效的数独

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

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
 

注意:一个有效的数独(部分已被填充)不一定是可解的。只需要根据以上规则,验证已经填入的数字是否有效即可。空白格用 '.' 表示。

   示例 1:

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

============================================================

我想到的思路就是遍历三遍,第一遍判断行,第二遍判断列,第三遍判断宫

上代码:

复制代码
class Solution {
public:
    bool isValidSudoku(vector<vector<char>>& board) {
        unordered_set<char> set;
        //遍历一遍行查找是否有重复的元素
        for (int j = 0; j < board.size(); j++) {
            for (int i = 0; i < board[j].size(); i++) {
                if (board[j][i] != '.') {
                    if (set.find(board[j][i]) != set.end())
                        return false;
                    set.emplace(board[j][i]);
                }
            }
            set.clear();
        }
        //遍历一遍列查找是否有重复的元素
        for (int i = 0; i < board[0].size(); i++) {
            for (int j = 0; j < board.size(); j++) {
                if (board[j][i] != '.') {
                    if (set.find(board[j][i]) != set.end())
                        return false;
                    set.emplace(board[j][i]);
                }
            }
            set.clear();
        }
        //遍历3v3来判断是否有重复的元素
        for (int i = 0; i <board.size(); i+=3) {
            for (int j = 0; j < 3; j++) {
                if (board[i][j] != '.') {
                    if (set.find(board[i][j]) != set.end())
                        return false;
                    set.emplace(board[i][j]);
                }
                if (board[i+1][j] != '.') {
                    if (set.find(board[i+1][j]) != set.end())
                        return false;
                    set.emplace(board[i+1][j]);
                }
                if (board[i +2][j] != '.') {
                    if (set.find(board[i + 2][j]) != set.end())
                        return false;
                    set.emplace(board[i + 2][j]);
                }
            }
            set.clear();
            for (int j = 3; j < 6; j++) {
                if (board[i][j] != '.') {
                    if (set.find(board[i][j]) != set.end())
                        return false;
                    set.emplace(board[i][j]);
                }
                if (board[i + 1][j] != '.') {
                    if (set.find(board[i + 1][j]) != set.end())
                        return false;
                    set.emplace(board[i + 1][j]);
                }
                if (board[i + 2][j] != '.') {
                    if (set.find(board[i + 2][j]) != set.end())
                        return false;
                    set.emplace(board[i + 2][j]);
                }
            }
            set.clear();
            for (int j = 6; j < 9; j++) {
                if (board[i][j] != '.') {
                    if (set.find(board[i][j]) != set.end())
                        return false;
                    set.emplace(board[i][j]);
                }
                if (board[i + 1][j] != '.') {
                    if (set.find(board[i + 1][j]) != set.end())
                        return false;
                    set.emplace(board[i + 1][j]);
                }
                if (board[i + 2][j] != '.') {
                    if (set.find(board[i + 2][j]) != set.end())
                        return false;
                    set.emplace(board[i + 2][j]);
                }
            }
            set.clear();
        }
        return true;
    }
};
复制代码

时间复杂度和空间复杂度都是O(n),后面看题解其实可以简化为遍历一遍

复制代码
class Solution {
public:
    bool isValidSudoku(vector<vector<char>>& board) {
        int row[9][10] = {0};// 哈希表存储每一行的每个数是否出现过,默认初始情况下,每一行每一个数都没有出现过
        // 整个board有9行,第二维的维数10是为了让下标有9,和数独中的数字9对应。
        int col[9][10] = {0};// 存储每一列的每个数是否出现过,默认初始情况下,每一列的每一个数都没有出现过
        int box[9][10] = {0};// 存储每一个box的每个数是否出现过,默认初始情况下,在每个box中,每个数都没有出现过。整个board有9个box。
        for(int i=0; i<9; i++){
            for(int j = 0; j<9; j++){
                // 遍历到第i行第j列的那个数,我们要判断这个数在其所在的行有没有出现过,
                // 同时判断这个数在其所在的列有没有出现过
                // 同时判断这个数在其所在的box中有没有出现过
                if(board[i][j] == '.') continue;
                int curNumber = board[i][j]-'0';
                if(row[i][curNumber]) return false; 
                if(col[j][curNumber]) return false;
                if(box[j/3 + (i/3)*3][curNumber]) return false;

                row[i][curNumber] = 1;// 之前都没出现过,现在出现了,就给它置为1,下次再遇见就能够直接返回false了。
                col[j][curNumber] = 1;
                box[j/3 + (i/3)*3][curNumber] = 1;
            }
        }
        return true;
    }
};。
复制代码

题目比较有意思的做法是位运算,位运算之前自己没有了解过,也没看懂代码。。。

 

posted on   4小旧  阅读(43)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示