当前位置: 首页 > news >正文

python做题日记(17)

第三十七题

        第三十七题是需要得到给定数独的解,可以按照暴力解数独的方法,每当遍历到一个空格位置,对该位置进行填数尝试,分别尝试1~9,检查在同行同列以及同3×3方格内是否存在相同的数字,如果存在相同的数字需要撤销刚才填入的数字,然后填入下一个数字,继续判断是否合理,如果不合理继续进行填入数字尝试,如果合理则对下一个空格处进行填入数字的尝试,因此就形成了编写代码的思路,写一个用于检查填入数字是否合理的函数,以及一个递归回溯函数,对数独进行解法。

class Solution:def solveSudoku(self, board: list[list[str]]) -> None:def is_valid(row, col, ch):# 检查行、列、3x3宫格是否合法for i in range(9):if board[row][i] == ch or board[i][col] == ch:return Falsestart_row, start_col = 3 * (row // 3), 3 * (col // 3)for i in range(3):for j in range(3):if board[start_row + i][start_col + j] == ch:return Falsereturn Truedef backtrack():for i in range(9):for j in range(9):if board[i][j] == '.':for ch in map(str, range(1, 10)):if is_valid(i, j, ch):board[i][j] = chif backtrack():return Trueboard[i][j] = '.'return Falsereturn Truebacktrack()

在检查函数中,就是简单的对于行,列以及同方格内的元素进行遍历,检查是否存在相同的数字,如果存在相同的数字则返回False,否则通过检查,返回True。对于递归回溯函数就是遍历数独,找到空格位置,对1~9数字进行循环填入尝试,没填入一个数就调入一次检查函数对其进行合理性检查,如果通过检查,则进行递归,对下一个空格进行尝试,如果发现后面的尝试过程中没有合理的数字可以填入,则撤销之前空格中填入的数字,对下一个数字进行尝试。最终的理想情况就是遍历完了整个数独,所有数字填入都是合理的,即找到了满足该数独的解。

代码优化

        在提交之后发现运行超时,说明需要对代码进行优化,减少递归调用的次数,因此需要先对数独进行遍历,记录每行每列以及每个3×3宫格内的数字,提高递归的效率。因为记录了每行每列以及每个3×3宫格内的数字,因此检查函数就可以简化为一行代码,即检查记录的集合中是否存在相同的数字,在每次填入或撤销数字的过程中都需要对记录集合进行更新,故有以下代码:

class Solution:def solveSudoku(self, board: list[list[str]]) -> None:rows = [set() for _ in range(9)]cols = [set() for _ in range(9)]boxes = [set() for _ in range(9)]empties = []for i in range(9):for j in range(9):if board[i][j] == '.':empties.append((i, j))else:rows[i].add(board[i][j])cols[j].add(board[i][j])boxes[(i//3)*3 + j//3].add(board[i][j])def backtrack(idx=0):if idx == len(empties):return Truei, j = empties[idx]box_idx = (i//3)*3 + j//3for ch in map(str, range(1, 10)):if ch not in rows[i] and ch not in cols[j] and ch not in boxes[box_idx]:board[i][j] = chrows[i].add(ch)cols[j].add(ch)boxes[box_idx].add(ch)if backtrack(idx + 1):return Trueboard[i][j] = '.'rows[i].remove(ch)cols[j].remove(ch)boxes[box_idx].remove(ch)return Falsebacktrack()

第三十八题

        第三十八题是需要返回外观数列的第n项,每一项都是源于上一项,初始数列为1。而外观数列的意思是将数列写成每个数字出现次数加上该数字的组合,即上一个数列中有几个几,再将它们组合在一起形成这一项的外观数列。故在代码中需要遍历上一项字符串,每次遍历需要记录重复数字出现的次数,直至下一个不同的数字出现,将已经记录的数字及其出现次数加入到结果外观数列中。故有以下代码:

class Solution:def countAndSay(self, n: int) -> str:res = "1"for _ in range(n - 1):cur = ""i = 0while i < len(res):count = 1while i + 1 < len(res) and res[i] == res[i + 1]:i += 1count += 1cur += str(count) + res[i]i += 1res = curreturn res

http://www.xdnf.cn/news/1041481.html

相关文章:

  • 15.vue.js的watch()和watchEffect()(2)
  • JAVA理论第十八章-JWT杂七杂八
  • Visualized_BGE 安装—多模态嵌入技术
  • Java 复习题选择题(1)(Java概述)
  • LLMs 系列实操科普(5)
  • 【卫星通信】Skylo与ViaSat标准建议详解:基于NB-IoT NTN通过GEO卫星实现IMS语音通话的解决方案
  • springboot在线BLOG网
  • SCADA|信创KingSCADA4.0历史报警查询的差异
  • 永磁同步电机控制算法--双矢量模型预测转矩控制MPTC(占空比)
  • [直播推流] 本地创建 nginx服务器
  • DataHub 架构设计与模块规划
  • 深度解析SpringBoot自动化部署实战:从原理到最佳实践
  • Android 安卓应用分身多开 适用于没有自带分身多开的Android设备,隐藏应用、应用锁、私密相册等管理,解锁永久Vip会员功能
  • 【精华】这样设计高性能短链生成系统
  • 记利用AI模型制作DataDump Scripts生成工具
  • 理解 C++ 的 this 指针
  • Seata与消息队列(如RocketMQ)如何实现最终一致性?
  • 【构建】CMake 构建系统重点内容
  • springboot音乐网站与分享平台
  • MySQL-DML语句深度解析与实战指南
  • 60天python训练计划----day52
  • Golang 在 Linux 平台上的并发控制
  • LeetCode - LCR 173. 点名
  • 基于深度学习的人类活动识别模型研究:HAR-DeepConvLG的设计与应用
  • 【大厂机试题解法笔记】恢复数字序列
  • Python开发功能实用
  • 关于钉钉的三方登录
  • 项目管理工具在并行管理中如何充分发挥作用
  • Python 使用 DrissionPage 模块进行爬虫
  • 【Linux网络】多路转接之select