题目:

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的更多相关文章

  1. [Leetcode][Python]37: Sudoku Solver

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 37: Sudoku Solverhttps://oj.leetcode.co ...

  2. leetcode 37. Sudoku Solver 36. Valid Sudoku 数独问题

    三星机试也考了类似的题目,只不过是要针对给出的数独修改其中三个错误数字,总过10个测试用例只过了3个与世界500强无缘了 36. Valid Sudoku Determine if a Sudoku ...

  3. 【LeetCode】37. Sudoku Solver

    Sudoku Solver Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are i ...

  4. [LeetCode] 37. Sudoku Solver 求解数独

    Write a program to solve a Sudoku puzzle by filling the empty cells. A sudoku solution must satisfy  ...

  5. Java [leetcode 37]Sudoku Solver

    题目描述: Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated ...

  6. leetcode problem 37 -- Sudoku Solver

    解决数独 Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated ...

  7. 【LeetCode题意分析&解答】37. Sudoku Solver

    Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by th ...

  8. [leetcode]37. Sudoku Solver 解数独

    Write a program to solve a Sudoku puzzle by filling the empty cells. A sudoku solution must satisfy  ...

  9. 37. Sudoku Solver *HARD*

    Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by th ...

随机推荐

  1. Spark 大数据平台 Introduction part 2 coding

    Basic Functions sc.parallelize(List(1,2,3,4,5,6)).map(_ * 2).filter(_ > 5).collect() *** res: Arr ...

  2. SOA Demo

    使用SOA来实现两个数字的相加,不包含验证,仅供练习使用. PDF文档下载地址:http://files.cnblogs.com/chenyongblog/SOA_Demo.pdf 源码下载:http ...

  3. Visual Assist X破解方法

    VC2008的破解方法:使用2008的朋友我就不多说了,直接拷贝到你选择的那个安装目录去,例如 C:\Program Files\Visual Assist\ ,直接运覆盖VA_X.dll 即可VC2 ...

  4. 【狼窝乀野狼】Excel那些事儿

    在工作中我们常常遇到Excel表格,不管是数据的导入导出,还是财务统计什么都,都离不开Excel,Excel是我见过的最牛逼的一个软件(可能我的见识少)没有之一:如果你只停留在Excel处理数据,统计 ...

  5. 2434: [Noi2011]阿狸的打字机 - BZOJ

    Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的 ...

  6. 【BZOJ】【3398】【USACO 2009 Feb】Bullcow 牡牛和牝牛

    组合计数/乘法逆元 排列组合求总方案数 这个可以用一个一维的动态规划解决: f[i][0]表示第i头牛是牝牛的方案数 f[i][1]表示第i头牛是牡牛的方案数 则转移为:f[i][0]=f[i-1][ ...

  7. Introduction to Deep Neural Networks

    Introduction to Deep Neural Networks Neural networks are a set of algorithms, modeled loosely after ...

  8. 【锋利的JQuery-学习笔记】Tootip(提示框)

    效果图: 1.当鼠标移动到超链接时,有提示框. 2..当鼠标移动到图片动画旋转 html: <div id="jnNotice"> <div id="j ...

  9. spring <context:component-scan>(转)

    在xml配置了这个标签后,spring可以自动去扫描base-pack下面或者子包下面的java文件,如果扫描到有@Component @Controller@Service等这些注解的类,则把这些类 ...

  10. jquery div层级选择器

    div id="modelName" class="modelName"> <!-- 车系的层 --> <div name=" ...