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; } };。
题目比较有意思的做法是位运算,位运算之前自己没有了解过,也没看懂代码。。。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了