一天一大 lee(解数独)难度:困难-Day20200915
时间:2022-07-25
本文章向大家介绍一天一大 lee(解数独)难度:困难-Day20200915,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题目:[1]
编写一个程序,通过已填充的空格来解决数独问题。
一个数独的解法需遵循如下规则:
数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。空白格用 '.' 表示。
数独
一个数独。
数独
答案被标成红色。
Note:
- 给定的数独序列只包含数字 1-9 和字符 '.' 。
- 你可以假设给定的数独只有唯一解。
- 给定数独永远是 9x9 形式的。
抛砖引玉
抛砖引玉
思路
- 对应任意一个字符 '.'填充的单元格,记录他所在行、列、3X3 子块传下过的数组
- 对其填充可能是数组,并且递归继续向后填充:
- 如果填充完所有符号'.'则直接结束
- 如果未填充完则说明填充错误,需要重置填充状态重新填充
填充数记录:
- 行:9X9 的矩阵 line[i][k],
- i 为行索引;
- k 是行内出现过的数字(恢复到 board 内元素需要+1);
- 值是否出现,出现过 true
- 列:9X9 的矩阵 column[i][k],
- i 为列索引;
- k 是行内出现过的数字(恢复到 board 内元素需要+1);
- 值是否出现,出现过 true
- 子块:3X3 的矩阵,内存放长度为 9 的数组 block[i][j][k],
- i 为行索引;
- j 为列索引;
- k 是行内出现过的数字(恢复到 board 内元素需要+1);
- 值是否出现,出现过 true
/**
* @param {character[][]} board
* @return {void} Do not return anything, modify board in-place instead.
*/
var solveSudoku = function(board) {
let line = Array.from({ length: 9 }, () => Array(9)),
column = Array.from({ length: 9 }, () => Array(9)),
// 3x3 宫
block = Array.from({ length: 3 }, () => Array(3)),
// 任意一种组合满足要求,终止递归
isEnd = false,
// 待填充的坐标
spaces = []
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
block[i][j] = Array(9)
}
}
// 初始化行、列、子块数据
for (let i = 0; i < 9; ++i) {
for (let j = 0; j < 9; ++j) {
if (board[i][j] == '.') {
spaces.push([i, j])
} else {
// 注意:数字是1-9,校验的行、列、子块数据索引是0-8,所以标记时值需要-1
let k = board[i][j] - 1,
// 子块坐标
x = parseInt(i / 3, 10),
y = parseInt(j / 3, 10)
line[i][k] = true
column[j][k] = true
block[x][y][k] = true
}
}
}
dfs(board, 0)
function dfs(board, index) {
if (index == spaces.length) {
isEnd = true
return
}
// 递归这个填充board中的字符 '.'
let [i, j] = spaces[index]
for (let k = 0; k < 9 && !isEnd; ++k) {
let x = parseInt(i / 3, 10),
y = parseInt(j / 3, 10)
// 行内、列内、子块内无当前枚举数字则填充
if (!line[i][k] && !column[j][k] && !block[x][y][k]) {
line[i][k] = true
column[j][k] = true
block[x][y][k] = true
board[i][j] = String(k + 1)
// 递归填充下一个,如果递归为遇到终止逻辑则说明本地填充错误
dfs(board, index + 1)
// 将填充状态恢复到未填充
line[i][k] = false
column[j][k] = false
block[x][y][k] = false
}
}
}
}
- 在一个空ASP.NET Web项目上创建一个ASP.NET Web API 2.0应用
- 小论线性变换
- 谈谈基于OAuth 2.0的第三方认证 [下篇]
- Razor Engine,实现代码生成器的又一件利器
- 谈谈基于OAuth 2.0的第三方认证 [上篇]
- 我所理解的RESTful Web API [Web标准篇]
- ASP.NET Web API中的Controller
- iOS 转场动画探究(二)
- Swift 面向对象解析(二)
- 谈谈基于OAuth 2.0的第三方认证 [中篇]
- [ASP.NET Web API]如何Host定义在独立程序集中的Controller
- ASP.NET Web API自身对CORS的支持: EnableCorsAttribute特性背后的故事
- 【黑客解析】黑客是如何实现数据库勒索的 ?
- 直播回看:高可用架构入门 —— 腾讯云架构演变及经验
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法