leetcode刷题-37解数独
题目
编写一个程序,通过已填充的空格来解决数独问题。
一个数独的解法需遵循如下规则:
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
空白格用 '.' 表示。
思路
使用暴力破解是不现实的,其需要 9^81次运算。
因此与数独相同,都需要用到回溯的思想。
其算法可以简化为:
1.从头开始选择到一个空白格
2.选择数字 1-9中的一个,判断是否符合标准(不能重复出现在行,列,3*3方格中)
2.1 填入数字
2.2 检查其是否已经找出了数独的解
2.2.1 若抵达最后一格,获得数独的解
2.2.2 若没有抵达最后一格,放置下一个数字
2.2.3 若不存在解,删除当前数字
实现
class Solution:
def solveSudoku(self, board: List[List[str]]) -> None:
"""
Do not return anything, modify board in-place instead.
"""
flag = False
line = [[]for i in range(9)]
arr = [[]for i in range(9)]
chunk = [[]for i in range(9)] def valid_num(num, row, col):
num_flag = num not in line[row] and num not in arr[col] and num not in chunk[row//3*3+col//3]
return num_flag def remove(num, row, col):
i = line[row].index(num)
j = arr[col].index(num)
k = chunk[row//3*3+col//3].index(num)
del line[row][i]
del arr[col][j]
del chunk[row//3*3+col//3][k]
board[row][col] = '.' def add(num, row, col):
line[row].append(num)
arr[col].append(num)
chunk[row//3*3+col//3].append(num)
board[row][col] = num def check(row, col):
if row == 8 and col == 8:
nonlocal flag
flag = True
else:
if col == 8:
backtrace(row + 1, 0)
else:
backtrace(row, col + 1) def backtrace(row, col):
if board[row][col] == '.':
for m in range(1,10):
d= str(m)
if valid_num(d, row, col) is True:
add(d, row, col)
check(row, col)
if not flag:
remove(d, row, col)
else:
check(row, col) vex = len(board)
for i in range(vex):
for j in range(vex):
get = board[i][j]
k = i//3*3+j//3
if get is not '.':
line[i].append(get)
arr[j].append(get)
chunk[k].append(get)
# flag = False
backtrace(0, 0)
值得注意的是,在check函数中,需要申明nonlocal flag在函数或其他作用域中使用外层(非全局)变量,因为其对flag值进行了修改,否则无法使用。此处不能使用global。
leetcode刷题-37解数独的更多相关文章
- Leetcode之回溯法专题-37. 解数独(Sudoku Solver)
Leetcode之回溯法专题-37. 解数独(Sudoku Solver) 编写一个程序,通过已填充的空格来解决数独问题. 一个数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次.数字 1 ...
- Java实现 LeetCode 37 解数独
37. 解数独 编写一个程序,通过已填充的空格来解决数独问题. 一个数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次. 数字 1-9 在每一列只能出现一次. 数字 1-9 在每一个以粗实 ...
- [leetcode] 37. 解数独(Java)(dfs,递归,回溯)
37. 解数独 1A 这个题其实15分钟左右就敲出来并且对了...但是由于我输错了一个数..导致我白白debug一个多小时.. 没啥难度,练递归-dfs的好题 class Solution { pri ...
- C#LeetCode刷题-哈希表
哈希表篇 # 题名 刷题 通过率 难度 1 两数之和 C#LeetCode刷题之#1-两数之和(Two Sum) 42.8% 简单 3 无重复字符的最长子串 24.2% 中等 18 四数之和 ...
- C#LeetCode刷题-回溯算法
回溯算法篇 # 题名 刷题 通过率 难度 10 正则表达式匹配 18.8% 困难 17 电话号码的字母组合 43.8% 中等 22 括号生成 64.9% 中等 37 解数独 45.8% ...
- LeetCode刷题 DFS+回溯
一.DFS介绍 二.LeetCode 实战 LC 17. 电话号码的字母组合 解法思路 解题步骤 代码 LC 79. 单词搜索 解题思路 解题步骤 代码 LC 46. 全排列 解题思路一 解题步骤 代 ...
- C#LeetCode刷题-二叉搜索树
二叉搜索树篇 # 题名 刷题 通过率 难度 220 存在重复元素 III 19.3% 中等 315 计算右侧小于当前元素的个数 31.9% 困难 327 区间和的个数 29.5% 困难 3 ...
- C#LeetCode刷题-字典树
字典树篇 # 题名 刷题 通过率 难度 208 实现 Trie (前缀树) 48.6% 中等 211 添加与搜索单词 - 数据结构设计 39.9% 中等 212 单词搜索 II 27.9% ...
- C#LeetCode刷题-树
树篇 # 题名 刷题 通过率 难度 94 二叉树的中序遍历 61.6% 中等 95 不同的二叉搜索树 II 43.4% 中等 96 不同的二叉搜索树 51.6% 中等 98 验证二叉搜索树 ...
随机推荐
- 图解比原链Tensority算法:如何让POW做到人工智能友好
共识算法说起 区块链系统首先是分布式系统,而一致性是分布式系统的基础问题,要保证系统满足不同程度的一致性,则就要用到共识算法. 现在主流的算法有POW.POS.DPOS等等,比特币采用的POW共识算法 ...
- c++萌新到大牛,要看哪些书?
基础语法 <c++primer> 语法进阶 <c++primer plus> 专为c++编著.支持c++14国际标准. 数据结构和算法 <大话数据结构> 编程规范 ...
- SqlServer 版本号
RTM (no SP) SP1 SP2 SP3 SP4 SQL Server 2014 codename Hekaton 12.00.2000.8 SQL Server 2012 ...
- Ansible常用模块-yum模块
yum模块 name 必选 指定安装包名 state 执行命令 present installed removed latest absent 其中installed and present等效 ...
- 【HDU3038】How Many Answers Are Wrong - 带权并查集
描述 TT and FF are ... friends. Uh... very very good friends -________-b FF is a bad boy, he is always ...
- jq js 获取子元素
js this.children[1].className=""this.firstChild.className = ""this.lastChild.cla ...
- 记录一次idae和maven设置的巨坑
这个忽略pom.xml文件千万别勾选,不然会导致项目的pom.xml怎么填写都无法导入新的依赖包!
- Jmeter 常用函数(31)- 详解 __iterationNum
如果你想查看更多 Jmeter 常用函数可以在这篇文章找找哦 https://www.cnblogs.com/poloyy/p/13291704.html 作用 获取当前线程的循环次数,跟线程组属性挂 ...
- Hbase写入流程图
写入流程图
- Erlang中的宏定义应该在什么时候用
读<Erlang OTP并发编程实战>中看到这么一句话,遂做笔记以记录: 宏不是函数的替代品,当你所需的抽象无法用普通函数来实现时,宏给出了一条生路,比如,必须确保在编译期展开某些代码的时 ...