题目:

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. Android实现发短信与打电话的功能

    //发短信 class SendMsgClickListener implements OnClickListener { public void onClick(View v) { //调用Andr ...

  2. openerp学习笔记 视图更新时删除已存在的菜单或其他对象

    删除菜单示例: <delete id="base.menu_module_updates" model="ir.ui.menu"/><dele ...

  3. opencv的初体验

    http://guoming.me/opencv-config  这篇文章有讲解opencv的安装与配置 一些常用库 opencv_core249d.lib opencv_imgproc249d.li ...

  4. html 布局;css3+jq 下拉菜单;table分页动态添加行;html5本地存储;简单易用的html框架

    简单好用的html框架,预览图见最后: 源码: 1.页面布局使用table: table 嵌套 +iframe 布局: 2.下拉菜单为jq+css3 动画; css input 无边框,select下 ...

  5. PAT乙级真题1008. 数组元素循环右移问题 (20)

    原题: 1008. 数组元素循环右移问题 (20) 时间限制400 ms内存限制65536 kB 一个数组A中存有N(N>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(M&g ...

  6. oracle-linux下挂载"移动硬盘" NTFS类型

    环境: ORACLE-LINUX 5.7 全新移动硬盘(未使用过) 移动硬盘空间3T 在默认情况下,Linux系统不支持NTFS分区挂载 1.服务器: A服务器和B服务器为一套ORACLE-RAC,移 ...

  7. StackExchange.Redis的使用

    StackExchange.Redis介绍 有需要了解的和基础的使用可以参考:http://www.cnblogs.com/bnbqian/p/4962855.html StackExchange.R ...

  8. Leetcode-Read N Characters Given Read4 II

    The API: int read4(char *buf) reads 4 characters at a time from a file. The return value is the actu ...

  9. 解决方法:java.lang.NoSuchMethodError: javax.persistence.Table.indexes()[Ljavax/persistence/Index;

    hibernate4.3版本 报错: 把实体注解的声明方式修改一下解决,如: 将 @Entity@Table(name=”table_name”)改为@Entity(name=”table_name” ...

  10. w3c_html_study_note_5.26

    xhtml+css 正确的说法 “DIV+CSS”叫法将网页制作者引入两大误区 [误区一]网页中用了Table,页面就不标准,甚至觉着用Table丢人,Table成为了判定页面是否标准的关键点. [误 ...