【PythonCode】力扣Leetcode6~10题Python版

【PythonCode】力扣Leetcode6~10题Python版

前言

力扣Leetcode是一个集学习、刷题、竞赛等功能于一体的编程学习平台,很多计算机相关专业的学生、编程自学者、IT从业者在上面学习和刷题。
在Leetcode上刷题,可以选择各种主流的编程语言,如C++、JAVA、Python、Go等。还可以在线编程,实时执行代码,如果代码通过了平台准备的测试用例,就可以通过题目。
本系列中的文章从Leetcode的第1题开始,记录我用Python语言提交的代码和思路,受个人能力限制,只是实现功能通过用例,我没有每题都研究最优的实现方法,供Python学习参考。

6. N 字形变换

将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:
在这里插入图片描述
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“PAHNAPLSIIGYIR”。

请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);

示例 1:
输入:s = “PAYPALISHIRING”, numRows = 3
输出:“PAHNAPLSIIGYIR”
示例 2:
输入:s = “PAYPALISHIRING”, numRows = 4
输出:“PINALSIGYAHRPI”
示例 3:
输入:s = “A”, numRows = 1
输出:“A”
提示:
1 <= s.length <= 1000
s 由英文字母(小写和大写)、‘,’ 和 ‘.’ 组成
1 <= numRows <= 1000

代码实现:

class Solution:def convert(self, s: str, numRows: int) -> str:if numRows == 1:return szlist = ["" for _ in range(numRows)]i, flag = 0, 1for a in s:zlist[i] += aif i == 0 or i == numRows-1:flag = -flagi -= flagreturn "".join(zlist)

解题思路:题目有两个输入,一个是字符串s,一个是行数numRows,最终要求输出的也是一个字符串。第一步,要将字符串s进行z字形排列,最后输出时,要按行来排列字符串,这里可以在代码中巧妙地满足这两个条件。创建一个列表,列表中先初始化三个空字符串,用列表的下标表示z字形排列时的行数,将字符串s中的每一个字符按z字形规则依次拼接到对应的行,最后再将列表中的字符串全部拼接返回。

再来看z字形规则如何排列,第一个字符从第一行开始排列,用一个变量i表示当前的行,用一个变量flag表示现在是向下排列还是向上排列,flag的值为1或-1,每从s中取完一个字符,即将行数减去flag,这样行数就会向下或向上变化。当移动到第一行或最后一行时,flag的值翻转。

当只有一行时,是题目的边界情况,此时z字形排列的结果即字符串本身,直接返回即可。

7. 整数反转

给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。

如果反转后整数超过 32 位的有符号整数的范围 [−2^31, 2^31 − 1] ,就返回 0。

假设环境不允许存储 64 位整数(有符号或无符号)。

示例 1:
输入:x = 123
输出:321
示例 2:
输入:x = -123
输出:-321
示例 3:
输入:x = 120
输出:21
示例 4:
输入:x = 0
输出:0
提示:
-2^31 <= x <= 2^31 - 1

代码实现:

class Solution:def reverse(self, x: int) -> int:y = str(x)num = int("-" + y[:0:-1]) if y[0] == "-" else int(y[::-1])return 0 if (num > 2 ** 31 - 1) or (num < -2 ** 31) else num

解题思路:这题虽然难度是中等,但其实实现比较简单。要将一个数字翻转,Python中可以直接将数字转换成字符串,用字符串切片的方式翻转,再转换回数字。因为输入数字可能是负数,所以做一次判断就行,并且题目要求,如果数字超过边界值时返回0,所以要判断一次结果的数字范围。代码可以直接用三元运算的语法来写,非常简洁。三元运算语法参考:详解Python中的三元运算。

8. 字符串转换整数 (atoi)

请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。

函数 myAtoi(string s) 的算法如下:

  • 读入字符串并丢弃无用的前导空格。
  • 检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。
  • 如果两者都不存在,则假定结果为正。 读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
  • 将前面步骤读入的这些数字转换为整数(即,“123” -> 123, “0032” -> 32)。如果没有读入数字,则整数为 0 。
  • 必要时更改符号(从步骤 2 开始)。 如果整数数超过 32 位有符号整数范围 [−2^31, 2^31 − 1],需要截断这个整数,使其保持在这个范围内。具体来说,小于 −2^31 的整数应该被固定为 −2^31 ,大于 2^31 − 1 的整数应该被固定为 2^31 − 1 。 返回整数作为最终结果。

注意:
本题中的空白字符只包括空格字符 ’ ’ 。
除前导空格或数字后的其余字符串外,请勿忽略任何其他字符。

示例 1:
输入:s = “42”
输出:42
解释:
第 1 步:“42”(当前没有读入字符,因为没有前导空格)
第 2 步:“42”(当前没有读入字符,因为这里不存在 ‘-’ 或者 ‘+’)
第 3 步:“42”(读入 “42”) 解析得到整数 42 。 由于 “42” 在范围 [-231, 231 - 1] 内,最终结果为 42 。
示例 2:
输入:s = " -42"
输出:-42
解释:
第 1 步:" -42"(读入前导空格,但忽视掉)
第 2 步:" -42"(读入 ‘-’ 字符,所以结果应该是负数)
第 3 步:" -42"(读入 “42”) 解析得到整数 -42 。 由于 “-42” 在范围 [-231, 231 - 1] 内,最终结果为 -42 。
示例 3:
输入:s = “4193 with words”
输出:4193
解释:
第 1 步:“4193 with words”(当前没有读入字符,因为没有前导空格)
第 2 步:“4193 with words”(当前没有读入字符,因为这里不存在 ‘-’ 或者 ‘+’)
第 3 步:“4193 with words”(读入 “4193”;由于下一个字符不是一个数字,所以读入停止) 解析得到整数 4193 。 由于 “4193” 在范围 [-231, 231 - 1] 内,最终结果为 4193 。
提示:
0 <= s.length <= 200
s 由英文字母(大写和小写)、数字(0-9)、’ ‘、’+‘、’-’ 和 ‘.’ 组成

代码实现:

class Solution:def myAtoi(self, s: str) -> int:s = s.strip()if not s:return 0flag = '+'if s[0] == '+':s = s[1:]elif s[0] == '-':s = s[1:]flag = '-'istr = ''for a in s:if a in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']:istr += aelse:breakif not istr:return 0num = int(flag+istr)if num < -2 ** 31:return -2 ** 31elif num > 2 ** 31 - 1:return 2 ** 31 - 1else:return num

解题思路:此题在题目中已经完整地描述了步骤,代码基本就是按照这些步骤来写,并且满足每一个步骤中的要求。题目说的字符串中是可以有非数字字符的,如果有非数字字符,则找到连续的最多的数字字符,将这些字符转换成整数,如果没有数字字符,则返回整数0。代码中用一个flag变量来记录数字的正负符号,最终转换整数时拼接上flag。转换完成之后再做一次边界判断。

9. 回文数

给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。

回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

例如,121 是回文,而 123 不是。

示例 1:
输入:x = 121
输出:true
示例 2:
输入:x = -121
输出:false
解释:从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例 3:
输入:x = 10
输出:false
解释:从右向左读, 为 01 。因此它不是一个回文数。
提示:
-2^31 <= x <= 2^31 - 1

代码实现:

class Solution:def isPalindrome(self, x: int) -> bool:return str(x) == str(x)[-1::-1]

解题思路:本题也比较简单,回文数要求正序和倒序读都一样,直接将数字转换成字符串,比较正序和倒序是否相等。不过这里也可以简单分析下,有两种比较明显的非回文数的情况,一是负数,二是正数中第一个数字不可能为0,所以如果整数的最后一个数字为0(能被10整除),则不是回文数。

10. 正则表达式匹配

给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。

‘.’ 匹配任意单个字符
‘*’ 匹配零个或多个前面的那一个元素

所谓匹配,是要涵盖 整个 字符串 s 的,而不是部分字符串。

示例 1:
输入:s = “aa”, p = “a”
输出:false
解释:“a” 无法匹配 “aa” 整个字符串。
示例 2:
输入:s = “aa”, p = “a*”
输出:true
解释:因为 ‘*’ 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 ‘a’。因此,字符串 “aa” 可被视为 ‘a’ 重复了一次。
示例 3:
输入:s = “ab”, p = “.*”
输出:true
解释:“.*” 表示可匹配零个或多个(‘*’)任意字符(‘.’)。
提示:
1 <= s.length <= 20
1 <= p.length <= 30
s 只包含从 a-z 的小写字母。
p 只包含从 a-z 的小写字母,以及字符 . 和 *。
保证每次出现字符 * 时,前面都匹配到有效的字符。

代码实现:

class Solution:def isMatch(self, s: str, p: str) -> bool:m, n = len(s), len(p)dp = [[False for _ in range(m+1)] for _ in range(n+1)]dp[0][0] = Truefor i in range(1, n+1):if p[i-1] == '*':if i-2 >= 0:dp[i][0] = dp[i-2][0]for i in range(1, n+1):for j in range(1, m+1):if p[i-1] == s[j-1] or p[i-1] == '.':dp[i][j] = dp[i-1][j-1]if p[i-1] == '*':dp[i][j] = dp[i-2][j]if p[i-2] == s[j-1] or p[i-2] == '.':dp[i][j] = dp[i][j] or dp[i][j-1]return dp[n][m]

解题思路:正则表达式中的 . 和 * 分别表示匹配任意一个字符和匹配前一个字符任意多次,现在需要自己写代码实现这两个规则。题目中的输入是两个字符串s和p,点号和星号是出现在字符串p中,我们的目标是实现正则表达式的规则,然后输出p是否能按正则的规则匹配到s。

每次从字符串p中取出一个字符或者 字符+星号 的组合,并在s中进行匹配。对于p中一个字符而言,它只能在s中匹配一个字符,匹配的方法具有唯一性,而对于p中 字符+星号 的组合而言,它可以在s中匹配任意自然数个字符,并不具有唯一性。因此,应从p的右侧往左侧来分析,如果p的最后一个字符是星号,星号仅能和它的前一个字符组合,如果p的最后一个字符不是星号,则它只能与s中的一个字符比较。这样从右往左分析,要判断s与p是否匹配,就是需要判断最右端是否匹配,以及剩余的子串是否匹配(子问题),这样就可以用动态规划的方法来求解。动态规划可以参考:循序渐进,搞懂什么是动态规划。

按照动态规划的解题步骤,第一步先定义问题的状态,用dp[i][j]表示p的前i个字符和s的前j个字符能否匹配,如果字符串p的长度为n,字符串s的长度为m,则dp[n][m]就是问题的答案。

第二步为列出状态转移方程,如果p[i]==s[j],说明p的第i个字符和s的第j个字符可以匹配,那么就看前面的字符是否可以匹配,状态转移方程:dp[i][j]=dp[i−1][j−1]。如果p[i]==‘.’,因为它可以代表任何字符,所以一定可以和s的第j个匹配上,也只需要看前面的字符是否可以匹配,状态转移方程:dp[i][j]=dp[i−1][j−1]。因为星号可以匹配0次、1次或多次,所以如果p[i]==‘*’,又需要分情况讨论。

如果p的第i个字符是星号,那么能不能与s的第j个字符匹配上,就看星号的前一个字符,也就是第i-1个字符。如果p[i-1]与s[j]匹配不上,那星号可以表示匹配0次,状态转移方程:dp[i][j]=dp[i−2][j]。如果p[i-1]与s[j]匹配,那么可以匹配上,此时星号表示匹配1次,同时,要考虑星号匹配多次的情况,也就是说,s[j]前还可能有与s[j]相等的字符,所以,这里p[i]的星号与p[i-1]的字符组合匹配s[j]后,p[i]的星号与p[i-1]继续保留,重复利用(这样就可以把匹配多次转换成反复匹配1次),直到遇到匹配0次的情况,p[i]的星号才利用完,状态转移方程:dp[i][j]=dp[i][j−1]。当然,这里并不是星号一定要匹配尽可能多的字符,可以介于于正则表达式中的“贪婪模式”与​“非贪婪模式”之间,比如点号和星号组合可以把s中的字符全部匹配完,但是字符串p的前面还有其他字符,所以这里点号和星号组合就不能全部匹配完,要留适当的一部分字符给p中前面的这些字符匹配,所以要允许状态不变,即dp[i][j]=dp[i][j]。

第三步为状态初始化,如果字符串s和字符串p都是空字符串,是可以匹配的,初始化为:dp[0][0]=True,并初始化一个长度为n+1乘m+1的dp数组。因为p中的星号可以表示0次,所以还有可能s为空,p不为空,如p=‘a*’, p='a*b*'等,这种情况s为空,在上面的状态转移方程中不存在s[j],所以也要进行初始化。

关于初始化,本题中还有一个注意事项,因为初始化dp[0][0]是字符串s和p都为空,所以字符串非空时,dp[i][j]中的i和j是从1开始的,而字符串的索引是从0开始的,所以索引要比状态编号减一,也就是说,上面的分析中,在代码中s或p的索引要再减1。同时,因为状态编号从1开始,所以代码需要遍历到m+1和n+1,也是dp数组大小为n+1乘m+1的原因。

当然,此题也可以用递归的方式实现,参考下方代码(不再具体分析了)。不过,使用递归时,时间复杂度满足不了力扣的要求,这就需要用到Python中的@cache装饰器,通过缓存来降低时间复杂度。参考:Python中的@cache有什么妙用?。

class Solution:def isMatch(self, s: str, p: str) -> bool:@cachedef DFS(i, j):if j == len(p):return i == len(s)firstMatch = i < len(s) and (s[i] == p[j] or p[j] == '.')if j + 1 < len(p) and p[j + 1] == '*':return DFS(i, j + 2) or (firstMatch and DFS(i + 1, j))return firstMatch and DFS(i + 1, j + 1)return DFS(0, 0)

相关阅读

PythonCode】力扣Leetcode1~5题Python版

📢欢迎 点赞👍 收藏⭐ 评论📝 关注 如有错误敬请指正!

☟ 学Python,点击下方名片关注我。☟

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

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

相关文章

我的尝试:Codigger + Vim

若您愿意耐心投入&#xff0c;学习 Vim 的过程其实远比想象中轻松。我对 Vim 产生兴趣&#xff0c;主要是源于它对提升生产力的巨大潜力。我尝试了 Neovim、NvChad 以及 Codigger Vim 插件&#xff0c;如今我的工作效率已远超从前。 那么&#xff0c;Vim 究竟是什么呢&#xff…

【调参】如何为神经网络选择最合适的学习率lr-LRFinder-for-Keras

【调参】如何为神经网络选择最合适的学习率lr-LRFinder-for-Keras_学习率选择-CSDN博客文章浏览阅读9.2k次&#xff0c;点赞6次&#xff0c;收藏55次。keras 版本的LRFinder&#xff0c;借鉴 fast.ai Deep Learning course。前言学习率lr在神经网络中是最难调的全局参数&#x…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:Navigator)

路由容器组件&#xff0c;提供路由跳转能力。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 可以包含子组件。 接口 Navigator(value?: {target: string, type?: NavigationType}) …

包冲突解决之-invalid constant type: 18

背景 现象一&#xff1a;引入了一个包A&#xff0c;服务突然起不来了&#xff0c;后台有报错信息&#xff0c;Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type xxx available: expected at least 1 bean which quali…

Day44-sersync企业实时复制实战

Day44-sersync企业实时复制实战 1. sersync实时复制工具介绍1.1 sersync工具简介1.2 sersync特点1.3 sersync图解原理1.4 sersyncrsync实时复制方案项目实践1.4.1 图解项目方案架构及实现原理1.4.2 确保远程数据传输服务部署完成1.4.3 检查当前系统nfs01是否支持inotify实时监控…

vue使用elementPlus ui框架,如何给Dialog 对话框添加Loading 自定义类名显示隐藏

vue使用elementPlus ui框架时&#xff0c;如何给Dialog 对话框添加Loading 自定义类名&#xff0c;想要实现dialog对话框区域有loading效果 官方给出的这个API配置项customClass&#xff0c;使用不太明确。暂时无法实现绑定class。 最后的实现方式&#xff1a; <template&…

吐槽FineDataLink工具Format函数处理日期转字符串格式的说明文档

一.背景 为公司师带徒的任务做些记录。 二.文档存在的问题 1.文档情况 FORMAT-格式转换- FineBI帮助文档 FineBI帮助文档 函数定义&#xff1a; FORMAT(object,format) formart的格式有哪些呢&#xff1f;我们截图看看&#xff1a; 2.文档说明不足问题 同事的需求是把时…

AI人工智能培训讲师ChatGPT讲师叶梓培训简历及提纲ChatGPT等AI技术在医疗领域的应用

叶梓&#xff0c;上海交通大学计算机专业博士毕业&#xff0c;高级工程师。主研方向&#xff1a;数据挖掘、机器学习、人工智能。历任国内知名上市IT企业的AI技术总监、资深技术专家&#xff0c;市级行业大数据平台技术负责人。 长期负责城市信息化智能平台的建设工作&#xff…

免费阅读篇 | 芒果YOLOv8改进109:注意力机制SimAM:用于卷积神经网络的简单、无参数注意力模块

免费阅读篇|芒果YOLOv8改进109&#xff1a;注意力机制篇SimAM&#xff1a;用于卷积神经网络的简单、无参数注意力模块 &#x1f4a1;&#x1f680;&#x1f680;&#x1f680;本博客 改进源代码改进 适用于 YOLOv8 按步骤操作运行改进后的代码即可 该专栏完整目录链接&#x…

RocketMQ学习笔记四(黑马)项目

课程地址&#xff1a; 1.Rocket第二章内容介绍_哔哩哔哩_bilibili &#xff08;视频35~88&#xff0c;搭建了一个电商项目&#xff09; 待学&#xff0c;待完善。

找准方向选CRM客户管理系统!2023年排行榜推荐

本文将为大家带来2023有哪些好用CRM客户管理系统&#xff1f;CRM系统排行榜基于品牌知名度、功能、产品实力、系统稳定性、用户体量等多重因素考量。其中Zoho CRM、红圈CRM等产品市场表现优异入选此次榜单。 1.Zoho CRM 公司成立时间&#xff1a;1996年 Zoho&#xff08;卓豪…

【算法】AC自动机的优化:增量更新与删除

一、概述 AC自动机&#xff08;Aho-Corasick Automation&#xff09;是著名的多模匹配算法&#xff0c;源于贝尔实验室&#xff0c;并且在实际应用中得到广泛的引用&#xff0c;且具有以下特点&#xff1a; 只需要扫描一次文本&#xff0c;即可获取所有匹配该文本的模式串复杂…

CSS扩展选择器

文章目录 1. 并集选择器2. 交集选择器3. 后代选择器4. 子代选择器5. 兄弟选择器5.1. 相邻兄弟选择器5.2. 通用兄弟选择器 6. 属性选择器7. 伪类选择器7.1. 动态伪类7.2. 结构伪类7.3. 否定伪类 8. 伪元素选择器9. Google 改进案例 1. 并集选择器 选中多个选择器对应的元素。一…

如何在Linux上使用git远程上传至gitee托管(add-commit-push指令详解)

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

力扣209. 长度最小的子数组

思路&#xff1a;题目是 数组和 > target&#xff0c;不是等于target 双指针法&#xff1a;用for循环中的 r 来界定右边界的下标&#xff0c;右边界每移动一位&#xff0c;左边界可能需要移动多位&#xff0c;所以内部再用while, 当满足 数组和>target时&#xff0c;记录…

C语言基础之结构体

文章目录 一、结构体1、结构体概述2、结构体类型的定义方式&#xff08;1&#xff09;先定义结构体类型&#xff0c;再定义结构体变量&#xff08;2&#xff09;结构体类型、变量同时定义&#xff08;3&#xff09;一次性结构体 3、结构体成员的初始化(1)结构体初始化(2)清空结…

RISC-V Optimization Guide(笔记)

官网发表的文章地址&#xff1a;RISC-V Optimization Guide B站有人做过解读视频&#xff0c;这篇文章也是看视频时做的笔记&#xff1a;视频地址 一、标量整数优化 1.1 常量的具体化 使用lui/addiw将立即数加载至寄存器&#xff0c;当立即数低12位的最高位为1时&#xff0c…

数据库 | MYSQL这个复杂系统如何上手?

当你不知道从何入手研究或解决一个复杂系统的问题时&#xff0c;通常意味着你没有找到合适的切入点或者缺乏对系统整体和细节之间联系的理解。在这种情况下&#xff0c;一个有用的策略是寻找系统的基本原理或构成要素。 小时候&#xff0c;你可能也玩过玩具四驱车。有的四驱车…

从零开始利用MATLAB进行FPGA设计(三)将Simulink模型转化为定点数据类型

文章灵感来源于MATLAB官方免费教程&#xff1a;HDL Coder Self-Guided Tutorial 考虑到MATLAB官网的英文看着慢&#xff0c;再加上视频讲解老印浓浓的咖喱味&#xff0c;我决定记录利用MATLAB&Simulink&SystemGenerator进行FPGA数字信号处理的学习过程。 往期回顾&am…

什么是响应式设计?响应式设计的基本原理是什么?如何做?

文章目录 一、是什么二、实现方式媒体查询百分比vw/vhrem小结 三、总结参考文献 一、是什么 响应式网站设计&#xff08;Responsive Web design&#xff09;是一种网络页面设计布局&#xff0c;页面的设计与开发应当根据用户行为以及设备环境(系统平台、屏幕尺寸、屏幕定向等)…