力扣 题目37-- 解数独
题目
题解
在力扣 题目36-- 有效的数独中我们判断了一个数独是否有效,
那么这题我们只要让填入每一个数字后的数独表 也是有效的即可,那么我们就可以利用36题的思路
但是问题是填入的数字会影响其他数字的填入也会导致数独表是否有效,
所以我们需要回溯法 当无法填入数字(1-9在九宫格/行/列都有)时应该回到上一个被填入的数字
修改上一个被填入的数字 用其他合法(满足数独表有效)数字填入 如果修改上一个也无法满足或者不能修改 那么继续回溯
当前面的数值改变之后 而且同样合法后,再继续填当前数字。
代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<vector> 3 using namespace std; 4 bool othersolveSudoku(vector<vector<char>>& board, vector<vector<bool>> other, vector<vector<bool>> row, vector<vector<bool>> column, int i, int j) { 5 //找i 与 j位置后的是.的位置 6 for (; i < board.size(); i++) { 7 for (; j < board[i].size(); j++) { 8 if (board[i][j] == '.') { 9 //找到了 所以要开始从1开始试 因为下标从0开始所以是0-9 10 for (int g = 0; g < 9; g++) { 11 //这里要找到对应.位置对应的九宫格的行 12 int blockIndex = i / 3 * 3 + j / 3; 13 //判断g是否在九宫格/行/列 重复 如果不重复就填入 14 //更新九宫格/行/列 保证不重复 15 if (!other[blockIndex][g] && !row[i][g] && !column[j][g]) { 16 other[blockIndex][g] = 1; 17 row[i][g] = 1; 18 column[j][g] = 1; 19 board[i][j] = g + 48 + 1;//这里别忘记+1 48是ASCII码值 用来转换字符 20 //递归调用 如果后面的都是true即 都可以填上数字那么此轮也应该有效 直接返回true 21 if (othersolveSudoku(board, other, row, column, i, j)) { 22 return true; 23 } 24 //如果后面有不能填入数字的则应该回溯即取消当前g造成的影响 并且继续g的循环 25 else 26 { 27 row[i][g] = 0; 28 column[j][g] = 0; 29 board[i][j] = '.'; 30 other[blockIndex][g] = 0; 31 } 32 } 33 } 34 //如果g全部循环完了 还是.只能说明无法填入数字 返回false 35 if (board[i][j] == '.') { 36 return false; 37 } 38 } 39 } 40 j = 0; 41 } 42 //如果没有.了 直接返回true 43 return true; 44 } 45 46 class Solution { 47 public: 48 void solveSudoku(vector<vector<char>>& board) { 49 vector<bool> load(9, 0); 50 //创建三个容器 分别记录九宫格 行 列 51 //使用int类型存放bool值 代表1-9 52 vector<vector<bool>> other(9, load);//九宫格 53 vector<vector<bool>> row(9, load);//行 54 vector<vector<bool>> column(9, load);//列 55 for (int i = 0; i < board.size();) { 56 for (int g = 0; g < 3; g++) { 57 for (int j = 0; j < board[i].size(); j++) { 58 //将char利用ASCII变为int 直接用int找下标看是否为1 是1表示已经存在返回false 不是则改为1表示存在 59 int num = board[i + g][j] - 49; 60 //将对应的数字变为1 表示已经存在过该数 61 //i + (j / 3)九宫格 62 //i + g行 63 //j列 64 if (board[i + g][j] != '.') { 65 other[i + (j / 3)][num] = 1; 66 row[i + g][num] = 1; 67 column[j][num] = 1; 68 } 69 } 70 } 71 i = i + 3; 72 } 73 //调用函数 74 othersolveSudoku(board, other, row, column, 0, 0); 75 } 76 }; 77 int main() { 78 Solution sol; 79 vector<vector<char>> board = { 80 {'5','3','.','.','7','.','.','.','.'} 81 ,{'6','.','.','1','9','5','.','.','.'} 82 ,{'.','9','8','.','.','.','.','6','.'} 83 ,{'8','.','.','.','6','.','.','.','3'} 84 ,{'4','.','.','8','.','3','.','.','1'} 85 ,{'7','.','.','.','2','.','.','.','6'} 86 ,{'.','6','.','.','.','.','2','8','.'} 87 ,{'.','.','.','4','1','9','.','.','5'} 88 ,{'.','.','.','.','8','.','.','7','9'} }; 89 sol.solveSudoku(board); 90 for (int i = 0; i < board.size(); i++) { 91 for (int j = 0; j < board[i].size(); j++) { 92 cout << board[i][j]; 93 } 94 cout << endl; 95 } 96 97 }