力扣 题目36-- 有效的数独
题目
题解
既然对行/列/九宫格有要求不能重复 那么我们把行/列/九宫格存放起来 然后判断是不是重复不就可以了。
先写三个容器 存放行/列/九宫格
1.字符放入
从上到下,从左往右 遍历(跳过. 具体遍历方法可以看代码) 先find一下看看原来的容器中有没有该字符 如果没有将遍历的字符放入三个容器(具体放入方法可以看代码)中 如果有直接返回false
2.伪放入
字符需要用find查找 时间上不理想 我们可以使用0和1代替是否已经存在
长度为9 即0-8 代表 1-9数字 然后字符的数字就是对应的下标
当该字符对应的下标所在的位置 为1则说明已经存在 返回false 如果是0不存在则改为1
代码
代码1 字符放入
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<vector> 3 using namespace std; 4 class Solution { 5 public: 6 bool isValidSudoku(vector<vector<char>>& board) { 7 bool result = true; 8 //创建三个容器 分别记录九宫格 行 列 9 //当然这里也可以使用int类型存放bool值 利用char的字符的数字直接去判断 也许更快速 10 vector<vector<char>> other;//九宫格 11 vector<vector<char>> row;//行 12 vector<vector<char>> column;//列 13 //重新填入大小 14 other.resize(9); 15 row.resize(9); 16 column.resize(9); 17 for (int i = 0; i < board.size();) { 18 int num = 0; 19 for (int g = 0; g < 3; g++) { 20 for (int j = 0; j < board[i].size(); j++) { 21 //查找当前指向的字符在九宫格/行/列中是否出现过 如果出现就直接返回false 22 //条件解析 23 //1.不为. 24 //2.find->查找函数 用法find(迭代器1,迭代器2,要查找的数) 找到返回对应迭代器 25 //找不到返回end()迭代器 26 if (board[i + g][j] != '.' 27 && (find(other[i + (j / 3)].begin(), other[i + (j / 3)].end(), board[i + g][j])!= other[i + (j / 3)].end() 28 || find(row[i + g].begin(), row[i + g].end(), board[i + g][j]) != row[i + g].end() 29 || find(column[j].begin(), column[j].end(), board[i + g][j]) != column[j].end()) 30 ) 31 { 32 return false; 33 } 34 //点没有用 所以没必要放进去 影响搜索时间 35 if (board[i + g][j] != '.') { 36 other[i + (j / 3)].push_back(board[i+g][j]); 37 row[i + g].push_back(board[i + g][j]); 38 column[j].push_back(board[i + g][j]); 39 } 40 } 41 } 42 i = i + 3; 43 } 44 45 return result; 46 } 47 }; 48 int main() { 49 Solution sol; 50 vector<vector<char>> board = { 51 {'5','3','.','.','7','.','.','.','.'} 52 ,{'6','.','.','1','9','5','.','.','.'} 53 ,{'.','9','8','.','.','.','.','6','.'} 54 ,{'8','.','.','.','6','.','.','.','3'} 55 ,{'4','.','.','8','.','3','.','.','1'} 56 ,{'7','.','.','.','2','.','.','.','6'} 57 ,{'.','6','.','.','.','.','2','8','.'} 58 ,{'.','.','.','4','1','9','.','.','5'} 59 ,{'.','.','.','.','8','.','.','7','9'} }; 60 bool result=sol.isValidSudoku(board); 61 cout << result << endl; 62 }
代码2 伪放入(代码应该可以进一步优化 空间更小一些 但是懒的优化了)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<vector> 3 using namespace std; 4 class Solution { 5 public: 6 bool isValidSudoku(vector<vector<char>>& board) { 7 bool result = true; 8 vector<bool> load(9, 0); 9 //创建三个容器 分别记录九宫格 行 列 10 //使用int类型存放bool值 代表1-9 11 vector<vector<bool>> other(9, load);//九宫格 12 vector<vector<bool>> row(9, load);//行 13 vector<vector<bool>> column(9, load);//列 14 for (int i = 0; i < board.size();) { 15 for (int g = 0; g < 3; g++) { 16 for (int j = 0; j < board[i].size(); j++) { 17 //将char利用ASCII变为int 直接用int找下标看是否为1 是1表示已经存在返回false 不是则改为1表示存在 18 int num = board[i + g][j] - 49; 19 if (board[i + g][j] != '.' 20 && (other[i + (j / 3)][num] == 1 21 || row[i + g][num] == 1 22 || column[j][num] == 1 23 ) 24 ) 25 { 26 return false; 27 } 28 //将对应的数字变为1 表示已经存在过该数 29 //i + (j / 3)九宫格 30 //i + g行 31 //j列 32 if (board[i + g][j] != '.') { 33 other[i + (j / 3)][num]=1; 34 row[i + g][num] = 1; 35 column[j][num] = 1; 36 } 37 } 38 } 39 i = i + 3; 40 } 41 42 return result; 43 } 44 }; 45 int main() { 46 Solution sol; 47 vector<vector<char>> board = { 48 {'5','3','.','.','7','.','.','.','.'} 49 ,{'6','.','.','1','9','5','.','.','.'} 50 ,{'.','9','8','.','.','.','.','6','.'} 51 ,{'8','.','.','.','6','.','.','.','3'} 52 ,{'4','.','.','8','.','3','.','.','1'} 53 ,{'7','.','.','.','2','.','.','.','6'} 54 ,{'.','6','.','.','.','.','2','8','.'} 55 ,{'.','.','.','4','1','9','.','.','5'} 56 ,{'.','.','.','.','8','.','.','7','9'} }; 57 bool result=sol.isValidSudoku(board); 58 cout << result << endl; 59 }