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

编写一个程序,通过已填充的空格来解决数独问题。

一个数独的解法需遵循如下规则:

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
空白格用 '.' 表示。

解法:

分析:

给定一个9*9的char型的二维数组,数组里已经填好了一些数字,要求生成一个数独。

本题可以用回溯法,在空的格子里填下1-9数字,全部填完后,判断是否为数独,是->保存退出,否->回溯,继续循环下一个数字。

 

判断当前坐标为:(row,col)的坐标点的行,列,方块区内是否满足条件的函数:

public boolean isValid(char board[][],int row, int col, char c) {
for (int i = 0; i < 9; i++) {
if (board[i][col] != '.' && board[i][col] == c)
return false; // 检查行
if (board[row][i] != '.' && board[row][i] == c)
return false; // 检查列
if (board[3 * (row / 3) + i / 3][3 * (col / 3) + i % 3] != '.'
&& board[3 * (row / 3) + i / 3][3 * (col / 3) + i % 3] == c)
return false; // 检查3x3小方格
}
return true;
}

AC代码为(这样写时间复杂有点高,后面再优化):

class Solution {
public boolean isValid(char board[][], int row, int col, char c) {
for (int i = 0; i < 9; i++) {
if (board[i][col] != '.' && board[i][col] == c)
return false; // 检查行
if (board[row][i] != '.' && board[row][i] == c)
return false; // 检查列
if (board[3 * (row / 3) + i / 3][3 * (col / 3) + i % 3] != '.'
&& board[3 * (row / 3) + i / 3][3 * (col / 3) + i % 3] == c)
return false; // 检查3x3小方格
}
return true;
} public boolean isValidSudoku(char[][] board) {
for (int i = 0; i < 9; i++) {
Set<Character> set = new HashSet<>();
boolean flag = true;
for (int j = 0; j < 9; j++) {
char ch = board[i][j];
if (ch == '.')
continue;
if (set.contains(ch) == true) {
flag = false;
}
set.add(ch);
} if (flag == false) {
return false;
}
}
for (int i = 0; i < 9; i++) {
Set<Character> set = new HashSet<>();
boolean flag = true;
for (int j = 0; j < 9; j++) {
char ch = board[j][i];
if (ch == '.')
continue;
if (set.contains(ch) == true) {
flag = false;
}
set.add(ch);
}
if (flag == false) {
return false;
}
} for (int a = 0; a < 3; a++) {
for (int b = 0; b < 3; b++) {
Set<Character> set = new HashSet<>();
boolean flag = true;
for (int i = a * 3; i < a * 3 + 3; i++) {
for (int j = b * 3; j < b * 3 + 3; j++) {
char ch = board[i][j];
if (ch == '.')
continue;
if (set.contains(ch) == true) {
flag = false;
}
set.add(ch); }
}
if (flag == false) {
return false;
}
}
} return true;
} char[][] ans = new char[9][9]; public void solveSudoku(char[][] board) { dfs(board, 0); for (int aa = 0; aa < 9; aa++) {
for (int bb = 0; bb < 9; bb++) {
board[aa][bb] = ans[aa][bb];
}
}
} public void dfs(char[][] board, int x) {
int i = x / 9;
int j = x % 9; if (x == 81) {
for (int aa = 0; aa < 9; aa++) {
for (int bb = 0; bb < 9; bb++) {
ans[aa][bb] = board[aa][bb];
}
}
return;
}
if (board[i][j] != '.') {
dfs(board, x + 1);
} else {
for (int k = 1; k <= 9; k++) {
if (isValid(board, i, j, (char) ('0' + k))) {
board[i][j] = (char) ('0' + k);
dfs(board, x + 1);
board[i][j] = '.';
}
}
} } }

Leetcode之回溯法专题-37. 解数独(Sudoku Solver)的更多相关文章

  1. Leetcode之回溯法专题-52. N皇后 II(N-Queens II)

    Leetcode之回溯法专题-52. N皇后 II(N-Queens II) 与51题的代码80%一样,只不过52要求解的数量,51求具体解,点击进入51 class Solution { int a ...

  2. Leetcode之回溯法专题-216. 组合总和 III(Combination Sum III)

    Leetcode之回溯法专题-216. 组合总和 III(Combination Sum III) 同类题目: Leetcode之回溯法专题-39. 组合总数(Combination Sum) Lee ...

  3. Leetcode之回溯法专题-212. 单词搜索 II(Word Search II)

    Leetcode之回溯法专题-212. 单词搜索 II(Word Search II) 给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在二维网格和字典中出现的单词. 单 ...

  4. Leetcode之回溯法专题-131. 分割回文串(Palindrome Partitioning)

    Leetcode之回溯法专题-131. 分割回文串(Palindrome Partitioning) 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回 s 所有可能的分割方案. ...

  5. Leetcode之回溯法专题-90. 子集 II(Subsets II)

    Leetcode之回溯法专题-90. 子集 II(Subsets II) 给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入 ...

  6. Leetcode之回溯法专题-79. 单词搜索(Word Search)

    Leetcode之回溯法专题-79. 单词搜索(Word Search) 给定一个二维网格和一个单词,找出该单词是否存在于网格中. 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元 ...

  7. Leetcode之回溯法专题-78. 子集(Subsets)

    Leetcode之回溯法专题-78. 子集(Subsets) 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: nums = ...

  8. Leetcode之回溯法专题-77. 组合(Combinations)

    Leetcode之回溯法专题-77. 组合(Combinations)   给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合. 示例: 输入: n = 4, k = 2 输 ...

  9. Leetcode之回溯法专题-51. N皇后(N-Queens)

    Leetcode之回溯法专题-51. N皇后(N-Queens) n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击. 上图为 8 皇后问题的一种解法. 给 ...

随机推荐

  1. hdu3416+hdu6582(最短路+最大流)

    题意 hdu3416: 给一个图,边不能重复选,问有多少个最短路 hdu6582: 给一个图,问最少删除边权多少的边后,最短路长度增加 分析 边不能重复选这个条件可以想到边权为1,跑最大流,所以我们可 ...

  2. 高级查询MYsql(二) 练习

    一.单词部分 ①exist存在②temp临时的③district区域 ④content内容⑤temporary暂时的 二.预习部分 1.表连接都可以用子查询替换吗 是的 2.检测某列是否存在某个范围可 ...

  3. PHP与ECMAScript_2_数据类型

    PHP ECMAScript 数据类型 基本:String.Integer.Float.Boolean 基本:String. Number. Boolean.NULL.undefined 复合:Arr ...

  4. 渐进式web应用开发-- 使用后台同步保证离线功能(六)

    _ 阅读目录 一:什么是后台同步保证离线功能呢? 二:后台同步是如何实现的呢? 三:如何给sync事件传递数据? 四:在我们的项目中添加后台同步功能 回到顶部 一:什么是后台同步保证离线功能呢? 在我 ...

  5. Java计时新姿势

    为获得更好的阅读体验,请访问原文:传送门 前言: 最近公司来了个大佬,从他那里学到不少东西,其中一个就是计时 的新姿势「StopWatch」,赶紧来一起了解了解吧! 一.最简单的计时 在我们的程序中不 ...

  6. PID算法 旋转倒立摆与平衡车的区别。此贴后边会更新。

    我做PID算法的背景和经历:本人之前电子信息科学与技术专业,对控制方向颇感兴趣,刚上大学时听到实验室老师说PID算法,那年在暑假集训准备全国电子设计竞赛,我正在练习做一个以前专科的题目,帆板角度控制系 ...

  7. CMD开放3389端口

    REG ADD HKLM\SYSTEM\CurrentControlSet\Control\Terminal" "Server /v fDenyTSConnections /t R ...

  8. 完全零基础在Linux中安装 JDK

    完全零基础在Linux中安装 JDK 总体思路:先确定没有Java程序了 — 然后创建相应路径文件夹 — 下载JDK — 解压到当前路径 — 自定义文件名称 — 配置环境变量 — 检查是否安装成功 第 ...

  9. Selenium+java - 借助autolt完成上传文件操作

    写在前面: 上传文件是每个自动化测试同学会遇到,而且可以说是面试必考的问题,标准控件我们一般用sendkeys()就能完成上传,但是我们的测试网站的上传控件一般为自己封装的,用传统的上传已经不好用了, ...

  10. 一个基于TCP/IP的服务器与客户端通讯的小项目(超详细版)

    1.目的:实现客户端向服务器发送数据 原理: 2.建立两个控制台应用,一个为服务器,用于接收数据.一个为客户端,用于发送数据. 关键类与对应方法: 1)类IPEndPoint: 1.是抽象类EndPo ...