https://oj.leetcode.com/problems/sudoku-solver/
九宫格数独问题。
一行上为1 2 3 到9
一列上为1 2 3 到9
每个小的3*3格子为 1 2 3 到9
使用深搜递归实现:
在技巧上,使用类的成员变量 vector<vector<char> > board; 这样不用每层递归都传递这个棋盘了
使用类的成员变量 bool flagOK; 标志是否已找到 solution.
从(0,0)位置开始递归,一个个位置加,直到位置到了最后一个。
在每一层上,遍历1 2 3 到 9 ,看看哪个数可以往这里放,然后递归下一层,即下一个位置。
当从下一个位置返回的时候,要把之前设置的值再 恢复 回来
还有个情况会导致返回到上一次,那就是从1 到 9 都遍历完了,仍然都不可以,也要记得恢复回来
class Solution { public: vector<vector<char> > board; bool flagOK; void solveSudoku(vector<vector<char> > &board) { if(board.empty()) return; flagOK = false; this->board = board; subSudoku(0,0); board = this->board; } // in rows and cols don't have the same one bool valide(char num, int p, int q) { bool flag = true; for(int i = 0; i < board.size(); i++) { if(num == board[i][q]) { flag = false; break; } } if(flag) { for(int j = 0; j < board.size(); j++) { if(num == board[p][j]) { flag = false; break; } } } return flag; } void subSudoku(int i, int j) { // till end find solution if(i == board.size()) { flagOK = true; return; } // num placed if(board[i][j] != '.') { if(j < board.size() - 1) { subSudoku(i,j + 1); if(flagOK == true) return; //不再递归了,已经找到答案了 } else { subSudoku(i+1,0); if(flagOK == true) return; } } else { char num; for(num = '1'; num <= '9'; num++) { // in its small cube bool OKSmallCube = true; int smallCubeI = i/3; int smallCubeJ = j/3; // check small cube for(int s = 0; s < 3; s++) { for(int m = 0; m < 3; m++) { if(board[smallCubeI*3 + s][smallCubeJ*3 + m] == num) { OKSmallCube = false; break; } } if(OKSmallCube == false) break; } if(OKSmallCube && valide(num,i,j)) { board[i][j] = num; if(j < board.size() - 1) { subSudoku(i,j + 1); if(flagOK == true) return; } else { subSudoku(i+1,0); if(flagOK == true) return; } } board[i][j] = '.'; //注意恢复原样 } board[i][j] = '.';//注意恢复原样 } } };