37. Sudoku Solver
题目:
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...
![]()
...and its solution numbers marked in red.
链接: http://leetcode.com/problems/sudoku-solver/
题解:
新加坡总理李显龙也做过的一题,还是用C做的,各种比特运算,巨快。思路就是DFS + Backtracking。在哪里回溯,怎样更好的构建DFS,需要多加练习。Knuth提到还有一种Dancing Links方法,用来构造回溯的,还不知道怎样使用。以及Boltzmann Machine。
Time Complexity - O(9m), Space Complexity - O(m), m是'.'的数目。
public class Solution {
public void solveSudoku(char[][] board) {
if(board == null || board.length == 0)
return;
trySolveSudokuDFS(board);
}
private boolean trySolveSudokuDFS(char[][] board) {
for(int row = 0; row < 9; row++) {
for(int col = 0; col < 9; col++) {
if(board[row][col] == '.') {
for(char num = '1'; num <= '9'; num++) {
if(isValid(board, row, col, num)) {
board[row][col] = num;
if(trySolveSudokuDFS(board)) //DFS
return true;
else
board[row][col] = '.'; //back-tracking
}
}
return false;
}
}
}
return true;
}
private boolean isValid(char[][] board, int row, int col, char c) {
for(int i = 0; i < 9; i++) //check if current col valid
if(board[i][col] == c)
return false;
for(int j = 0; j < 9; j++) //check if current row valid
if(board[row][j] == c)
return false;
for(int i = row / 3 * 3; i < row / 3 * 3 + 3; i++) { //check if current block valid
for(int j = col / 3 * 3; j < col / 3 * 3 + 3 ; j++) {
if(board[i][j] == c)
return false;
}
}
return true;
}
}
二刷:
根一刷使用的方法一样。主要还是DFS+ Backtracking。这里需要重新建立一个boolean类型的method canSolveSudoku,然后根据这个method来进行DFS。每次DFS之前,我们要先对'.'的位置进行预判断,检查是否能够放置从‘1’ - ‘9’的字符,假如可以,则我们设定这个位置的字符,之后进行DFS。否则我们尝试下一个字符。当DFS失败的时候,我们要backtracking,把这个位置的值重新设置为'.'。由于这个method canSolveSudoku是对于整个矩阵进行的dfs,所以在if block结束的时候我们就可以知道是否存在这样一个解, 我们可以在这里放一个 return false来提前终止循环,因为所有的条件我们都已经判断过了。
这里dfs的time complexity, braching factor是9 ,深度是'.'的个数m,所以时间复杂度是O(9m),空间复杂度是O(9m) = O(m)。
Time Complexity - O(9m), Space Complexity - O(m)
Java:
public class Solution {
public void solveSudoku(char[][] board) {
canSolveSudoku(board);
}
private boolean canSolveSudoku(char[][] board) {
if (board == null || board.length == 0) {
return false;
}
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board.length; j++) {
if (board[i][j] == '.') {
for (char c = '1'; c <= '9'; c++) {
if (isCurrentBoardValid(board, i, j, c)) {
board[i][j] = c;
if (canSolveSudoku(board)) {
return true;
} else {
board[i][j] = '.'; // backtracking
}
}
}
return false;
}
}
}
return true;
}
private boolean isCurrentBoardValid(char[][] board, int row, int col, char c) {
for (int i = 0; i < board.length; i++) {
if (board[i][col] == c) {
return false;
}
}
for (int j = 0; j < board[0].length; j++) {
if (board[row][j] == c) {
return false;
}
}
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 (board[i][j] == c) {
return false;
}
}
}
return true;
}
}
Reference:
https://en.wikipedia.org/wiki/Dancing_Links
http://www.csc.kth.se/utbildning/kth/kurser/DD143X/dkand12/Group6Alexander/final/Patrik_Berggren_David_Nilsson.report.pdf
https://leetcode.com/discuss/30482/straight-forward-java-solution-using-backtracking
37. Sudoku Solver的更多相关文章
- [Leetcode][Python]37: Sudoku Solver
# -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 37: Sudoku Solverhttps://oj.leetcode.co ...
- leetcode 37. Sudoku Solver 36. Valid Sudoku 数独问题
三星机试也考了类似的题目,只不过是要针对给出的数独修改其中三个错误数字,总过10个测试用例只过了3个与世界500强无缘了 36. Valid Sudoku Determine if a Sudoku ...
- 【LeetCode】37. Sudoku Solver
Sudoku Solver Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are i ...
- [LeetCode] 37. Sudoku Solver 求解数独
Write a program to solve a Sudoku puzzle by filling the empty cells. A sudoku solution must satisfy ...
- Java [leetcode 37]Sudoku Solver
题目描述: Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated ...
- leetcode problem 37 -- Sudoku Solver
解决数独 Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated ...
- 【LeetCode题意分析&解答】37. Sudoku Solver
Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by th ...
- [leetcode]37. Sudoku Solver 解数独
Write a program to solve a Sudoku puzzle by filling the empty cells. A sudoku solution must satisfy ...
- 37. Sudoku Solver *HARD*
Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by th ...
随机推荐
- spring-mysqlclient开源了
https://github.com/risedragon/spring-mysqlclient/wiki/spring-mysqlclient-user-guide 开源了一个项目,总结了几年的数据 ...
- MVC中的几个问题汇总
1.The model backing the 'XXXXDBContext' context has changed since the database was created. Either m ...
- angular事件代理
在angular中,是不支持事件代理的,有些时候,我们需要处理比较多的数据,尤其是一些列表的时候,可能会很多,如果给每一项都加事件的话,注定慢很多,为了解决这个事情,因此需要一个做事件代理的direc ...
- Unix无缓冲文件操作函数、文件信息查询
问题描述: Unix无缓冲文件操作函数.文件信息查询 问题解决: struct stat 结构体信息: 具体代码: 具体源文件:
- Centos——rpm和yum
间歇性的学习了centos的一些使用,发现一段时间不操作,就会忘掉其中的概念或者操作方式方法,于是在此总结一下. 一.问题描述 首先,把一个我最常忘记的概念性的东西在这里记录一下: 什么是yum,什么 ...
- sql查询结果本身要被使用两次
一.问题 查询用户所有的错题数目到前端展示,要求展示的时候要有错题的编号,从1开始递增.如果删除了第5题,则将后面的题编号均向前挪. 二.分析 错题是在用户每次做题过程中插入到错题表中的,或者将题目推 ...
- 01-04-03【Nhibernate (版本3.3.1.4000) 出入江湖】Criteria API关联查询
Criteria API关联查询 如果说HQL查询还有需要了解点SQL语法知识,并不是完全彻底面向对象查询, 那么Criterial API就是完全面向对象的查询方式. public IList< ...
- java poi导出EXCEL xls文件代码
String _currentPage = request.getParameter("currentPage"); Integer currentPage = 0; if(_cu ...
- Cent Os 常用操作
开放端口 编辑iptables文件(/etc/sysconfig/iptables) -A INPUT -m state --state NEW -m tcp -p tcp --dport xx端口号 ...
- Codeforces400D Dima and Bacteria
题意:给你一个无向有权的图,图上的点被分成了几类,对于同类的点你需要判断它们之间相互的最短距离是不是0.满足这个条件之后要输出的是类与类之间的最短距离的矩阵.点给到10^5这么多,判断同类的点显然不能 ...