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.

做了这道题,对backtracking的理解又加深了一点点。

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

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

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

4 所有的方案(k从1到9)完毕之后,应该返回错误,这个是不应该被忽略的。

5 最后一点需要注意的是,当i,j循环完毕之后,第36行应该返回true。这里实际上是最终/最底层的一次循环,表明已经解出了sudoku,返回true!切记切记,最终情况!

 public class Solution {
public boolean solveSudoku(char[][] board) {
// Note: The Solution object is instantiated only once and is reused by each test case.
for (int i = 0; i < 9; i ++){
for (int j = 0; j < 9; j ++)
{
if (board[i][j] == '.')
{
for (int k = 1; k <= 9; k ++)
{
board[i][j] = (char)(k + '0');
if (isValid(board, i, j) && solveSudoku(board)){
return true;
}
board[i][j] = '.';
}
return false;
}
}
}
return true;
}
public boolean isValid(char[][] board, int x, int y){
int i = 0;
int j = 0;
for (; i < 9; i++)
if (i != x && board[i][y] == board[x][y])
return false;
for (; j < 9; j++)
if (j != y && board[x][j] == board[x][y])
return false;
for (i = 3 * (x / 3); i < 3 * (x / 3 + 1); i++)
for (j = 3 * (y / 3); j < 3 * (y / 3 + 1); j++)
if (i != x && j != y && board[i][j] == board[x][y])
return false;
return true;
}
}

第三遍:

 public class Solution {
public boolean solveSudoku(char[][] board) {
for(int i = 0; i < 9; i ++)
for(int j = 0; j < 9; j ++)
if(board[i][j] == '.'){
for(int k = 1; k < 9; i ++){
board[i][j] = (char)(k + '0');
if(isValid(board, i , j) && solveSudoku(board)) return true;
board[i][j] = '.';
}
return false;
}
return true;
} public boolean isValid(char[][] board, int a, int b){
for(int i = 0; i < 9; i ++){
if(i != a && board[a][b] == board[i][b]) return false;
if(i != b && board[a][b] == board[a][i]) return false;
}
for(int i = 3 * (a / 3); i < 3 * (a / 3) + 3; i ++)
for(int j = 3 * (b / 3); j < 3 * (b / 3) + 3; i ++)
if(i != a && j != b && board[i][j] == board[a][b]) return false;
return true;
}
}

Sudoku Solver的更多相关文章

  1. Leetcode 笔记 36 - Sudoku Solver

    题目链接:Sudoku Solver | LeetCode OJ Write a program to solve a Sudoku puzzle by filling the empty cells ...

  2. LeetCode:Valid Sudoku,Sudoku Solver(数独游戏)

    Valid Sudoku Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku bo ...

  3. [leetcode]算法题目 - Sudoku Solver

    最近,新加坡总理李显龙也写了一份代码公布出来,大致瞧了一眼,竟然是解数独题的代码!前几天刚刚写过,数独主要算法当然是使用回溯法.回溯法当时初学的时候在思路上比较拧,不容易写对.写了几个回溯法的算法之后 ...

  4. 【leetcode】Sudoku Solver

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

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

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

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

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

  7. 【LeetCode】37. Sudoku Solver

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

  8. Valid Sudoku&&Sudoku Solver

    Valid Sudoku Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku bo ...

  9. LeetCode解题报告—— Reverse Nodes in k-Group && Sudoku Solver

    1. Reverse Nodes in k-Group Given a linked list, reverse the nodes of a linked list k at a time and ...

  10. Leetcode之回溯法专题-37. 解数独(Sudoku Solver)

    Leetcode之回溯法专题-37. 解数独(Sudoku Solver) 编写一个程序,通过已填充的空格来解决数独问题. 一个数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次.数字 1 ...

随机推荐

  1. java非静态变量初始化

    java费静态变量的初始化分为两种情况,一种是局部变量,一种是类的域. 对于类的域,java在类初始化时,会为变量赋一个初始值.对于基本数据类型,java会将初始值设置为二进制0,具体为将boolea ...

  2. Java--CJDP

    was定义,包定义, 1. Java的接口概念 进行封装,方便的使用 2. 包定义,Java 中多种包,进行迁移使用,包的导入,例如对数据库的操作Hibernate 3. 配置文件xml和json,对 ...

  3. 3月3日(5) Roman to Integer

    原题 Roman to Integer 题意很简单,把Roman字母翻译成int. 实现方式也不难,针对每个字符转成int,从右往左,依次判断,如果当前值比上一个值大则相加,小则相减. 什么,你问我怎 ...

  4. 观察者模式(Observer)

    观察者模式是经常使用到的一种设计模式,在我们的生活中也经常遇到,小到学校上学让同学帮忙看着老师有没有过来,在教室里做一些与学习无关的事情,大到股市里面我们遇到的,到股票涨到或者跌到一定程度的时候通知我 ...

  5. NaN属性,isNaN函数

    NaN:Not a Number,顾名思义,表示不是一个数字. 可以把 Number 对象设置为该值,来指示其不是数字值. 使用 isNaN() 全局函数来判断一个值是否是 NaN 值 详见 Java ...

  6. dmp文件导入

    dmp文件导入 1,打开“开始”-->输入cmd—> sqlplus log: 2,输入 conn / as sysdba管理员账户登录: 3,需要创建表空间,如果我们知道需要导入的数据库 ...

  7. gulp插件

    gulp是趋势 gulp完全开发指南 => 快来换掉你的Grunt吧 gulp的工作流程:文件流--文件流--文件流......因为grunt操作会创建临时文件,会有频繁的IO操作,而gulp使 ...

  8. RGB颜色二值化

    原理:RGB颜色根据计算'灰度'的公式,可以转化为黑白2种颜色,实现二值化. 业务场景的应用:可以根据背景颜色,取一个黑色或白色的颜色,作为背景色上的文案字体颜色 具体代码: function get ...

  9. flex 监听网络连接情况

    NativeApplication.nativeApplication.addEventListener(Event.NETWORK_CHANGE, onNetworkChange); private ...

  10. Android屏幕像素密度适配详解

    讲到像素密度,我们先要搞明白什么是像素密度,像素密度的字面上的意思为手机屏幕上一定尺寸区域内像素的个数.在Android开发中, 我们一般会使用每英寸像素密度(dpi)这样一个单位来表示手机屏幕的像素 ...