37. Sudoku Solver
2015-07-21 17:41
337 查看
这样的题目一般通过回溯法求解,设置某个空格时,如果该空格无论设置什么数字都无法达到合法状态,那么回溯重新设置上一个空格,详见代码注释。注意,这样的题目一定要想明白每一处细节,才能够作对。代码如下:
class Solution { public: void solveSudoku(vector<vector<char> > &board) { for(int i = 0; i < 9; i++) for(int j = 0; j < 9; j++) if(board[i][j] != '.') fill(i, j, board[i][j] - '0'); solver(board, 0); } bool solver(vector<vector<char> > &board, int index) {// 0 <= index <= 80,index表示接下来要填充第index个格子 if(index > 80)return true; int row = index / 9, col = index - 9*row; if(board[row][col] != '.') return solver(board, index+1); for(int val = '1'; val <= '9'; val++)//每个为填充的格子有9种可能的填充数字 { if(isValid(row, col, val-'0'))// 可以填充的有效数字 { board[row][col] = val; fill(row, col, val-'0'); //更新填充状态 if(solver(board, index+1))return true; //如果此路可以走通,返回true clear(row, col, val-'0'); //此路走不通,清除状态 } } board[row][col] = '.';//注意别忘了恢复board状态 return false; //填9个数字都没有办法,找到一条走通的路,则返回false } //判断在第row行col列填充数字val后,是否是合法的状态 bool isValid(int row, int col, int val) { if(rowValid[row][val] == 0 && columnValid[col][val] == 0 && subBoardValid[row/3*3+col/3][val] == 0) return true; return false; } //更新填充状态 void fill(int row, int col, int val) { rowValid[row][val] = 1; columnValid[col][val] = 1; subBoardValid[row/3*3+col/3][val] = 1; } //清除填充状态 void clear(int row, int col, int val) { rowValid[row][val] = 0; columnValid[col][val] = 0; subBoardValid[row/3*3+col/3][val] = 0; } private: int rowValid[9][10];//rowValid[i][j]表示第i行数字j是否已经使用 int columnValid[9][10];//columnValid[i][j]表示第i列数字j是否已经使用 int subBoardValid[9][10];//subBoardValid[i][j]表示第i个小格子内数字j是否已经使用 };
相关文章推荐
- dd命令简单易用,例如
- vs2015正式版,建立安卓工程报错:值不能为空,参数名:path1的错误解决
- nginx+ISS 负载均衡 快速入门
- AgularJS中Unknown provider: $routeProvider解决方案
- JS向右弹出DIV,点击可向左隐藏。我用jquery可以从左下角像右上角隐藏,怎么从做向右隐藏呢?
- 数据库创建
- ffDrop的架构设计
- 深入浅出 ES6-Generator
- Linux中TCP listen()的backlog参数详解
- 杭电 1860 统计字符
- iOS_网络请求_代理方式
- 纯代码sizeclass使用
- 剑指offer:二进制中1的个数
- iphone下元素放在了一个position: fixed的div中无法点击
- thinkphp自动映射分析
- webview
- GRE写作必备句型
- 杭电1090 a+b(2)
- 省市区数组
- iOS 常用动画方法