Leetcode之回溯法专题-37. 解数独(Sudoku Solver)
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)的更多相关文章
- Leetcode之回溯法专题-52. N皇后 II(N-Queens II)
Leetcode之回溯法专题-52. N皇后 II(N-Queens II) 与51题的代码80%一样,只不过52要求解的数量,51求具体解,点击进入51 class Solution { int a ...
- Leetcode之回溯法专题-216. 组合总和 III(Combination Sum III)
Leetcode之回溯法专题-216. 组合总和 III(Combination Sum III) 同类题目: Leetcode之回溯法专题-39. 组合总数(Combination Sum) Lee ...
- Leetcode之回溯法专题-212. 单词搜索 II(Word Search II)
Leetcode之回溯法专题-212. 单词搜索 II(Word Search II) 给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在二维网格和字典中出现的单词. 单 ...
- Leetcode之回溯法专题-131. 分割回文串(Palindrome Partitioning)
Leetcode之回溯法专题-131. 分割回文串(Palindrome Partitioning) 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回 s 所有可能的分割方案. ...
- Leetcode之回溯法专题-90. 子集 II(Subsets II)
Leetcode之回溯法专题-90. 子集 II(Subsets II) 给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入 ...
- Leetcode之回溯法专题-79. 单词搜索(Word Search)
Leetcode之回溯法专题-79. 单词搜索(Word Search) 给定一个二维网格和一个单词,找出该单词是否存在于网格中. 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元 ...
- Leetcode之回溯法专题-78. 子集(Subsets)
Leetcode之回溯法专题-78. 子集(Subsets) 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: nums = ...
- Leetcode之回溯法专题-77. 组合(Combinations)
Leetcode之回溯法专题-77. 组合(Combinations) 给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合. 示例: 输入: n = 4, k = 2 输 ...
- Leetcode之回溯法专题-51. N皇后(N-Queens)
Leetcode之回溯法专题-51. N皇后(N-Queens) n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击. 上图为 8 皇后问题的一种解法. 给 ...
随机推荐
- File文件类
目录 File文件类 File类的构造方法 File类的创建功能 File类的重命名 File类的删除功能 File类的判断功能 File类的获取功能 文件名称过滤器 File文件类 File:文件和 ...
- web-fragment模块化使用
用eclipse右键new->other->web->web fragment project 确定后修改dynamic web project name为你要输出到的项目,当然可以 ...
- 金蝶K3 V12.2版本,中途启用双计量单位出现错误
忘记修改虚仓库存/收料通知单的双计量数量
- 【Android】Mac Android adb 配置
打开终端,输入下面命令: touch .bash_profile open -e .bash_profile 即新建 “.bash_profile” 文件,并会弹出 “.bash_profile” 文 ...
- spring boot 学习笔记(一)之前端文件配置
一.叙述 spring boot 由于是内置的tomcat ,因此其在独立运行的时候,是不需要单独安装 tomcat,这使其前端文件(CSS.JS.html)等放置的位置与war中的不同. 二.常见配 ...
- iOS基础面试题汇总
目录 1. #import 跟#include.@class有什么区别?#import<> 跟 #import""又什么区别? 都可以完整包含某个文件的内容,但是#im ...
- 【JDK】JDK源码分析-CountDownLatch
概述 CountDownLatch 是并发包中的一个工具类,它的典型应用场景为:一个线程等待几个线程执行,待这几个线程结束后,该线程再继续执行. 简单起见,可以把它理解为一个倒数的计数器:初始值为线程 ...
- .net core使用ocelot---第一篇 简单使用
简介原文地址 接下来你会学习,基于asp.net core 用Ocelot实现一个简单的API网关.或许你会疑问什么是API网关,我们先看下面的截图 API网关是访问你系统的入口,它包括很多东西,比如 ...
- 并发编程(3)——ThreadPoolExecutor
ThreadPoolExecutor 1. ctl(control state) 线程池控制状态,包含两个概念字段:workerCount(线程有效数量)和runState(表示是否在运行.关闭等状态 ...
- 1、JAVA的小白之路
大学的时光过得很快,转眼我已经大二了,在大一时,学习了C\C++,对于语言有一定基础,在未来的道路上,我需要攒足干劲,积累足够的知识和技能,去走上社会. 我的第一任大学班主任告诉我:“作为程序员,你至 ...