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 ...
随机推荐
- Sql Server数据库
1.表分区 http://www.cnblogs.com/huangxincheng/p/3565755.html 2.MVP教程地址:http://www.cnblogs.com/lyhabc/p/ ...
- oracle建用户
create user ng_zj identified by ng_zjdefault tablespace tbs_testtemporary tablespace tbs_test_tmp; g ...
- android----sqlite中的 query() 参数分析
public Cursor query (String table, String[] columns, String selection, String[] selectionArgs, Strin ...
- 基于FPGA的线阵CCD图像测量系统研究——笔记
本文是对基于FPGA的线阵CCD图像测量系统研究(作者:高尚)的阅读笔记 第一章绪论 1. 读读看 读了前面的摘要依然没有看懂作者要做什么.接着往下读....终于看到了一个字眼“基于机器视觉的图像测量 ...
- java之redis篇(spring-data-redis整合)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...
- 【学习总结】iOS 数据保存几种方式总结
在iOS开发过程中,不管是做什么应用,都会碰到数据保存的问题.将数据保存到本地,能够让程序的运行更加流畅,不会出现让人厌恶的菊花形状,使得用户体验更好.下面介绍一下数据保存的方式: NSKeyedAr ...
- 【BZOJ 1188】 [HNOI2007]分裂游戏
Description 聪聪和睿睿最近迷上了一款叫做分裂的游戏. 该游戏的规则试: 共有 n 个瓶子, 标号为 0,1,2.....n-1, 第 i 个瓶子中装有 p[i]颗巧克力豆,两个人轮流取豆子 ...
- Ruby 语法快速入门
作用域:指的是类,模块,方法 常量:无需指定类型,全大写 FANS = 100 puts "We have" + FANS.to_s + "fans" 变量 局 ...
- Codeforces Round #Pi (Div. 2) E. President and Roads 最短路+桥
题目链接: http://codeforces.com/contest/567/problem/E 题意: 给你一个带重边的图,求三类边: 在最短路构成的DAG图中,哪些边是必须经过的: 其他的(包括 ...
- BZOJ1692: [Usaco2007 Dec]队列变换
1692: [Usaco2007 Dec]队列变换 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 594 Solved: 246[Submit][Sta ...