回溯——13.解数独

力扣题目链接

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

一个数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。 空白格用 '.' 表示。

解题思路

  1. 回溯法:数独是一种经典的约束满足问题(CSP),其求解方法通常是回溯法。回溯法的基本思想是尝试为每一个空格填入一个数字,然后递归地尝试填入下一个空格。当遇到冲突(即不能满足数独规则)时,回溯并尝试其他数字。
  2. 数独规则:在数独中,每个空格需要满足三个条件:
    • 在同一行中不重复。
    • 在同一列中不重复。
    • 在同一个3x3的小方块中不重复。
  3. 递归与回溯:在每个空格尝试填入1到9的数字,递归地进行填充。如果某个数字不符合条件,则回溯并尝试其他数字。

完整代码如下:

class Solution:def solveSudoku(self, board: List[List[str]]) -> None:"""Do not return anything, modify board in-place instead."""self.backtracking(board)def backtracking(self, board: List[List[str]]) -> bool:# 若有解,返回True;若无解,返回Falsefor i in range(len(board)): # 遍历行for j in range(len(board[0])):  # 遍历列# 若空格内已有数字,跳过if board[i][j] != '.': continuefor k in range(1, 10):if self.is_valid(i, j, k, board):board[i][j] = str(k)if self.backtracking(board): return Trueboard[i][j] = '.'# 若数字1-9都不能成功填入空格,返回False无解return Falsereturn True # 有解def is_valid(self, row: int, col: int, val: int, board: List[List[str]]) -> bool:# 判断同一行是否冲突for i in range(9):if board[row][i] == str(val):return False# 判断同一列是否冲突for j in range(9):if board[j][col] == str(val):return False# 判断同一九宫格是否有冲突start_row = (row // 3) * 3start_col = (col // 3) * 3for i in range(start_row, start_row + 3):for j in range(start_col, start_col + 3):if board[i][j] == str(val):return Falsereturn True
def solveSudoku(self, board: List[List[str]]) -> None:self.backtracking(board)
  • 这是主函数,它调用了 backtracking 函数来解决数独。
  • 传入的参数 board 是一个二维列表,表示数独的9x9网格。
def backtracking(self, board: List[List[str]]) -> bool:# 若有解,返回True;若无解,返回Falsefor i in range(len(board)):  # 遍历行for j in range(len(board[0])):  # 遍历列# 若空格内已有数字,跳过if board[i][j] != '.': continuefor k in range(1, 10):if self.is_valid(i, j, k, board):board[i][j] = str(k)if self.backtracking(board): return Trueboard[i][j] = '.'# 若数字1-9都不能成功填入空格,返回False无解return Falsereturn True  # 有解
  • 遍历整个数独:使用两层循环遍历 board 中的每个位置 (i, j)。如果当前位置不是空的(即不等于 '.'),则跳过。
  • 尝试填数字:对于每一个空格,尝试填入数字1到9。
    • 调用 is_valid 函数判断数字 k 是否可以填入 (i, j) 位置。
    • 如果可以,则将 board[i][j] 设为 k,然后递归调用 backtracking 函数尝试解决下一个空格。
    • 如果递归返回 True,表示找到了一个可行解,则直接返回 True
    • 如果递归返回 False,则将 board[i][j] 重新置为 '.',表示回溯。
  • 返回结果:如果遍历了所有位置都找不到一个合法的数字,则返回 False,表示无解。如果成功填满整个数独,则返回 True
def is_valid(self, row: int, col: int, val: int, board: List[List[str]]) -> bool:# 判断同一行是否冲突for i in range(9):if board[row][i] == str(val):return False# 判断同一列是否冲突for j in range(9):if board[j][col] == str(val):return False# 判断同一九宫格是否有冲突start_row = (row // 3) * 3start_col = (col // 3) * 3for i in range(start_row, start_row + 3):for j in range(start_col, start_col + 3):if board[i][j] == str(val):return Falsereturn True
  • 行检查:遍历当前行 row,检查数字 val 是否已存在。如果存在则返回 False
  • 列检查:遍历当前列 col,检查数字 val 是否已存在。如果存在则返回 False
  • 3x3方块检查:找到当前空格所属的3x3小方块的起始位置 (start_row, start_col),然后检查这个方块内是否存在数字 val
  • 返回结果:如果数字 val 在行、列和3x3方块中都不存在,则返回 True,表示可以在 (row, col) 填入数字 val

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/879445.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

中国矿业大学《2023年868+2007年自动控制原理真题》 (完整版)

本文内容,全部选自自动化考研联盟的:《25届中国矿业大学868自控考研资料》的真题篇。后续会持续更新更多学校,更多年份的真题,记得关注哦~ 目录 2007年复试真题 2023年初试真题 Part1:完整版真题 2007年复试真题 2…

Qt 定时器-定时备份

定时备份 在Qt 中&#xff0c;可以使用QTimer类来实现定时备份功能。以下是一个示例代码&#xff0c;每隔一段时间自动执行备份操作&#xff1a; #include <QTimer>QTimer timer; int backupInterval 24 * 60 * 60 * 1000;//备份间隔为24小时connect(&timer, &…

feign client发送Post请求,发送对象参数,服务端接收不到正确参数报错排查

记一次feignclient发送请求服务端接收不到正确参数排查 服务端代码&#xff1a; Operation(summary "Create team")PostMapping("post")RequiresPermissions("team:add")public RestResponse addTeam(Valid Team team) {this.teamService.crea…

Android应用性能优化

Android手机由于其本身的后台机制和硬件特点&#xff0c;性能上一直被诟病&#xff0c;所以软件开发者对软件本身的性能优化就显得尤为重要&#xff1b;本文将对Android开发过程中性能优化的各个方面做一个回顾与总结。 Cache优化 ListView缓存&#xff1a; ListView中有一个回…

SpringCloud(八)配置中心服务化和高可用

在前两篇的介绍中&#xff0c;客户端都是直接调用配置中心的server端来获取配置文件信息。这样就存在了一个问题&#xff0c;客户端和服务端的耦合性太高&#xff0c;如果server端要做集群&#xff0c;客户端只能通过原始的方式来路由&#xff0c;server端改变IP地址的时候&…

【25.3】C++智能交友系统

仿照上篇文章&#xff0c;编写boy类&#xff0c;代码如下 头文件 #pragma once #include <string>using namespace std;class Girl; class Boy { public:Boy();Boy(int age, string name, int salary);~Boy();int getAge() const;string getName() const;int getSalary…

FreeRTOS-临界段保护及任务调度器的挂起和恢复

FreeRTOS-临界段保护及任务调度器的挂起和恢复 一、临界段保护简介二、临界段代码保护函数介绍三、任务调度器的挂起和恢复 一、临界段保护简介 临界区运用首先在任务创建实验里临界段代码又叫临界区&#xff0c;是指那些必须完整运行&#xff0c;不能被打断(中断或者任务调度…

Kafka 命令详解及使用示例

文章目录 Kafka 命令详解及使用示例Kafka 命令详解kafka-topics.sh&#xff1a;主题管理创建主题创建带副本的主题修改主题分区数了解分区分布列出主题查看主题详情删除主题 kafka-console-producer.sh&#xff1a;消息生产者发送消息到主题带键值对的消息消息生产性能优化带分…

Knife4j:打造优雅的SpringBoot API文档

1. 为什么需要API文档&#xff1f; 在现代软件开发中,API文档的重要性不言而喻。一份清晰、准确、易于理解的API文档不仅能够提高开发效率,还能降低前后端沟通成本。今天,我们要介绍的Knife4j正是这样一款强大的API文档生成工具,它专为Spring Boot项目量身打造,让API文档的生成…

【Python基础】Python错误和异常处理(详细实例)

本文收录于 《Python编程入门》专栏&#xff0c;从零基础开始&#xff0c;分享一些Python编程基础知识&#xff0c;欢迎关注&#xff0c;谢谢&#xff01; 文章目录 一、前言二、Python中的错误类型三、Python异常处理机制3.1 try-except语句3.2 try-except-else语句3.3 try-fi…

TiDB 扩容过程中 PD 生成调度的原理及常见问题丨TiDB 扩缩容指南(一)

导读 作为一个分布式数据库&#xff0c;扩缩容是 TiDB 集群最常见的运维操作之一。本系列文章&#xff0c;我们将基于 v7.5.0 具体介绍扩缩容操作的具体原理、相关配置及常见问题的排查。 通常&#xff0c;我们根据当前资源状态来决定是否需要调整 TiKV 节点的规模&#xff0…

探索螺钉设计:部分螺纹与全螺纹,哪种更适合你的项目?

为什么有些螺钉有部分螺纹? 螺钉由头部、柄部和尖端组成&#xff0c;是世界上zui常用的紧固件之一。与螺栓一样&#xff0c;它们旨在将多个对象或表面连接在一起。但是&#xff0c;在比较不同类型的螺钉时&#xff0c;您可能会注意到其中一些都具有部分螺纹杆。 什么是螺柄&a…

Python | Leetcode Python题解之第397题整数替换

题目&#xff1a; 题解&#xff1a; class Solution:def integerReplacement(self, n: int) -> int:ans 0while n ! 1:if n % 2 0:ans 1n // 2elif n % 4 1:ans 2n // 2else:if n 3:ans 2n 1else:ans 2n n // 2 1return ans

滚雪球学SpringCloud[2.3]:服务发现与负载均衡详解

全文目录&#xff1a; 前言1. Ribbon的使用与配置1.1 Ribbon 概述Ribbon 的核心功能&#xff1a; 1.2 Ribbon 的基本使用1.2.1 引入 Ribbon 依赖1.2.2 配置 RestTemplate 与 Ribbon1.2.3 示例&#xff1a;通过 Ribbon 调用服务 1.3 Ribbon 的配置选项 2. Ribbon的负载均衡策略2…

Python_两个jpg图片文件名称互换

项目场景 处理Adobe Photoshop导出的两个切片的顺序错误问题 小编在进行图片切片处理的时候&#xff0c;发现用PS导出的切片顺序错误&#xff0c;例如用PS导出的切片分别为test_01.jpg&#xff0c;test_02.jpg&#xff0c;但实际的使用需求是将两个图片的顺序调换&#xff0c…

self-play RL学习笔记

让AI用随机的路径尝试新的任务&#xff0c;如果效果超预期&#xff0c;那就更新神经网络的权重&#xff0c;使得AI记住多使用这个成功的事件&#xff0c;再开始下一次的尝试。——llya Sutskever 这两天炸裂朋友圈的OpenAI草莓大模型o1和此前代码能力大幅升级的Claude 3.5&…

three.js KeyframeTrack

KeyframeTrack 关键帧轨道(KeyframeTrack)是关键帧(keyframes)的定时序列, 它由时间和相关值的列表组成, 用来让一个对象的某个特定属性动起来。 在使用手册的“下一步”章节中&#xff0c;“动画系统”一文对three.js动画系统中的不同元素作出了概述 和JSON model format的…

基于less和scss 循环生成css

效果 一、less代码 复制代码 item-count: 12; // 生成多少个 .item 类.item-loop(n) when (n > 0) {.icon{n} {background: url(../../assets/images/menu/icon{n}.png) no-repeat;background-size: 100% 100%;}.item-loop(n - 1);}.item-loop(item-count);二、scss代码 f…

c++临时对象导致的生命周期问题

对象的生命周期是c中非常重要的概念&#xff0c;它直接决定了你的程序是否正确以及是否存在安全问题。 今天要说的临时变量导致的生命周期问题是非常常见的&#xff0c;很多时候没有一定经验甚至没法识别出来。光是我自己写、review、回答别人的问题就犯了或者看到了许许多多这…

TCL一面(HR)

1. 假设你是正在面试前端开发工程师的候选人&#xff0c;面试官让你详细讲一讲你作为队长参加支付宝小程序开发者大赛&#xff0c;你的作品是“甲骨文猜谜与探索”&#xff0c;请你讲一讲反思、收获和亮点。 在我作为队长参加支付宝小程序开发者大赛的过程中&#xff0c;我们的…