Write a program to solve a Sudoku puzzle by filling the empty cells.

Empty cells are indicated by the character '.'.

You may assume that there will be only one unique solution.

A sudoku puzzle...

1 每个backtracking的题目,最好都有独立判断isValid的程序,这样架构清楚。同时,valid判断函数在这里可以稍微研究一下。只要当前要判断的位置上的数值和本行没有重复,本列没有重复,九宫格没有重复就可以。一旦重复立即返回,减少判断次数。

2 backtracking的递归函数,怎么能没有返回值呢?!因为要判断递归的方案正确与否,所以这里的递归一定是有返回值的(除非是combination那种没有正确错误概念的backtracking)!

3 可以考虑“先放置,再判断”的方案。比如这里,首先判断当前位置是否为空,如果为空,那么放置一个元素,检查它是否正确。如果正确,就继续进行下面的递归(也就是第29行 isValid&&solveSudoku的作用)。当函数返回错误之后,将刚刚的数值变为空,再进行下一次尝试即可。

5 最后一点需要注意的是,当i,j循环完毕之后,表明已经解出了sudoku,需要返回!切记切记,最终情况!

简单地说思路就是循环处理子问题,对于每个格子,带入不同的9个数,然后判合法,如果成立就递归继续,结束后把数字设回空。大家可以看出代码结构和N-Queens是完全一样的。判合法其实在这里因为每次进入时已经保证之前的board不会冲突,所以不需要判断整个盘,只需要看当前加入的数字和之前是否冲突就可以,这样可以大大提高运行效率,毕竟判合法在程序中被多次调用。

class Solution {
public void solveSudoku(char[][] board) {
helper(board,0,0);
}
//判断row,col位置是否为'.',是的话就设置值。
//因为要判断是否正确,所以需要返回值
public boolean helper(char[][] board,int row,int col){
if(col>=9){ //下一个位置超出列,就是进行下一行
return helper(board,row+1,0);
}
if(row==9){
return true;
}
//如果该位置是'.',则要添加数字
if(board[row][col]=='.'){
//依次给该位置添加1-9
for(int k=1;k<=9;k++){
board[row][col]=(char)(k+'0');
if(isValid(board,row,col)){//如果有效,就进行下一个位置添加
if(helper(board,row,col+1))//如果后面的添加返回true,表明添加成功,返回true,否则就尝试下一个k
return true;
}
board[row][col]='.';
}
}else{
return helper(board,row,col+1);
}
return false;
}
/*
前面都已经判断了,只要判断该位置添加数字后是否符合要求,也就是看该行、列有没有和该元素相同的,而且该位置所在的九宫格中也不能有和它相同的
*/
public boolean isValid(char[][] board,int row,int col){
//判断列是否有相同的,再同列不同行,元素却相同
for(int i=0;i<9;i++){
if(i!=row&&board[i][col]==board[row][col])
return false;
}
//判断行是否有相同的,同行不同列
for(int j=0;j<9;j++){
if(j!=col&&board[row][col]==board[row][j])
return false;
} //判断该位置所在九宫格是否有相同的
/*要根据该位置找到所在九宫格的行和列的范围
每个九宫格的行的范围是0-2,3-5,6-8,
*/
for(int i=row/3*3;i<row/3*3+3;i++)
{
for(int j=col/3*3;j<col/3*3+3;j++){
if((i!=row||j!=col)&&board[i][j]==board[row][col])
return false;
}
} return true;
}
}

最新文章

  1. 追MM的各种算法
  2. Android4.4中不能发送SD卡就绪广播
  3. C++学习40 抛出自己的异常
  4. spring 中的两个DaoSupport类的使用对比
  5. do {...} while (0) in macros
  6. 工作&ldquo;触雷&rdquo;经历与总结--记博弈论的应用
  7. 生意经:研究一下国外SAAS的产品线,比如Salesforce、Netsuite和Zendesk等等(Salesforce斥资7.5亿美元收购云计算字处理应用Quip)
  8. VC++ SetLayeredWindowAttributes 部分窗口透明鼠标穿透
  9. Code4 APP
  10. 我的第一个python web开发框架(28)——定制ORM(四)
  11. 连接H3C交换机的Console口连不上
  12. CentOS系统/tmp目录里面的文件默认保留多久
  13. LeetCode 106. Construct Binary Tree from Inorder and Postorder Traversal 由中序和后序遍历建立二叉树 C++
  14. C语言结构体变量私有化
  15. 个人作业Week1
  16. Java中的Graphics2D类基本使用教程
  17. js 的filter()方法
  18. android获取APP 包名和activity
  19. spring boot更换日志为log4j2
  20. 【[POI2000]病毒】

热门文章

  1. Quick-Cocos2d-X 捋一捋框架流程
  2. Java进阶(三十二) HttpClient使用详解
  3. MySQL数据库内置函数
  4. ntoskrnl符号在IDA中查看的问题
  5. Spring - IOC简介
  6. Uva - 810 - A Dicey Problem
  7. C++ Primer 有感(标准库set类型)
  8. Linux0.11 创建进程的过程分析--fork函数的使用
  9. Lambda的使用与实战
  10. UIScrollView&amp;nbsp;UIPageViewControlle…