【PythonCode】力扣Leetcode6~10题Python版

news2025/1/9 1:37:43

【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 s
        zlist = ["" for _ in range(numRows)]
        i, flag = 0, 1
        for a in s:
            zlist[i] += a
            if i == 0 or i == numRows-1:
                flag = -flag
            i -= flag
        return "".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 0
        flag = '+'
        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 += a
            else:
                break
        if not istr:
            return 0
        num = int(flag+istr)
        if num < -2 ** 31:
            return -2 ** 31
        elif num > 2 ** 31 - 1:
            return 2 ** 31 - 1
        else:
            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] = True
        for 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:
        @cache
        def 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.coloradmin.cn/o/1520497.html

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

相关文章

渐开线花键不是齿轮?

在和一位小伙伴交流时&#xff0c;他认为齿轮和花键不一样&#xff0c;那花键是不是齿轮呢&#xff1f;老师傅们可以绕开了&#xff0c;我觉得对于一些平时接刚刚接触齿轮&#xff0c;或者很少接触的朋友来说&#xff0c;还是有必要聊一聊这个话题。 首先这个问题并不严谨&…

包冲突解决之-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…

CSS扩展选择器

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

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实时监控…

智慧城市:提升城市治理能力的关键

目录 一、智慧城市的概念及特点 二、智慧城市在提升城市治理能力中的应用实践 1、智慧交通&#xff1a;提高交通治理效率 2、智慧政务&#xff1a;提升政府服务水平 3、智慧环保&#xff1a;加强环境监测与治理 4、智慧安防&#xff1a;提高城市安全水平 三、智慧城市在…

基于springboot的七彩云南文化旅游网站的设计与实现(论文+源码)_kaic

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装七彩云南文化旅游网站软件来发挥其高效地信息处理的作用&am…

sqllab第二十三关通关笔记

知识点&#xff1a; mysqli_query() 返回值为资源型或布尔型如果内容为查询语句则返回资源型数据&#xff1b;如果内容为插入、更新、删除等语句则返回布尔类型结果mysql_fetch_array() 从结果集中取出一行作为关联数组或数字数组输入内容为指定查询的结果集单引号闭合绕过联…

【测试开发学习历程】Docker入门

前言&#xff1a; Linux命令到上一篇博文就可以告一个段落了哦 ~ ~ 今天初步学习在测试中很重要的东西&#xff1a;Docker 目录 1 Docker概述 1.1 Docker产生的背景&#xff1f; 1.2 Docker的理念&#xff1f; 1.3 Docker的优势 1.3.1 传统的虚拟机 1.3.2 容器化虚拟技…

异次元发卡源码系统/荔枝发卡V3.0二次元风格发卡网全开源源码

– 支付系统&#xff0c;已经接入易支付及Z支付免签接口。 – 云更新&#xff0c;如果系统升级新版本&#xff0c;你无需进行繁琐操作&#xff0c;只需要在你的店铺后台就可以无缝完成升级。 – 商品销售&#xff0c;支持商品配图、会员价、游客价、邮件通知、卡密预选&#…

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

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

Github 2024-03-16 Rust开源项目日报 Top10

根据Github Trendings的统计,今日(2024-03-16统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Rust项目10TypeScript项目2Go项目1RustDesk: 用Rust编写的开源远程桌面软件 创建周期:1218 天开发语言:Rust, Dart协议类型:GNU Affero Gene…

OCP NVME SSD规范解读-12.Telemetry日志要求

以NVME SSD为例&#xff0c;通常大家想到的是观察SMAR-log定位异常&#xff0c;但是这个信息在多数情况下无法只能支撑完整的定位链路。 定位能力的缺失和低效是数据中心问题解决最大的障碍。 为了解决这个问题&#xff0c;Meta的做法是推进OCP组织加入延迟记录页面。同时NVME协…

经典机器学习模型(一)感知机模型

经典机器学习模型(一)感知机模型 感知机可以说是一个相当重要的机器学习基础模型&#xff0c;是神经网络和支持向量机的基础。 感知机是一个二分类的线性分类模型&#xff0c;之所以说是线性&#xff0c;是因为它的模型是线性形式的。 从《统计学习方法》中&#xff0c;我们…

如何搭建“Docker Registry私有仓库,在CentOS7”?

1、下载镜像Docker Registry docker pull registry:2.7.1 2、运行私有库Registry docker run -d -p 5000:5000 -v ${PWD}/registry:/var/lib/registry --restartalways --name registry registry:2.7.1 3、拉取镜像 docker pull busybox 4、打标签&#xff0c;修改IP&#x…

基于直方图均衡化的图像去雾算法,Matlab实现

博主简介&#xff1a; 专注、专一于Matlab图像处理学习、交流&#xff0c;matlab图像代码/项目合作可以联系&#xff08;QQ:3249726188&#xff09; 个人主页&#xff1a;Matlab_ImagePro-CSDN博客 原则&#xff1a;代码均由本人编写完成&#xff0c;非中介&#xff0c;提供有偿…

Spring-1

目录 概念 优点 Autowired和Resource关键字 相同点 不同点 依赖注入的三种方式 概念 Spring 是个java企业级应用的开源开发框架。Spring主要用来开发Java应用&#xff0c;但是有些扩展是针对构建J2EE&#xff08;Java平台企业版&#xff09;平台的web应用。Spring 框架目…

熔断降级的方案实现

熔断降级的方案实现 Spring Cloud Netflix Hystrix 提供线程隔离、服务降级、请求缓存、请求合并等功能可与Spring Cloud其他组件无缝集成官方已宣布停止维护&#xff0c;推荐使用Resilience4j代替 Spring Cloud Resilience4j 轻量级服务熔断库 提供类似于Hystrix的功能 具有更…

鸿蒙-自定义组件的生命周期

目录 自定义组件的生命周期 1.aboutToAppear 2.aboutToDisappear 3.onPageShow 4.onPageHide 5.onBackPress 日志输出 1.显示页面 2.页面点击返回按钮 3.页面跳转 4.页面返回 自定义组件的生命周期 先来一段列子 import router from ohos.router Entry Component…

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

可以附加在单个组件上用于信息标记的容器组件。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 支持单个子组件。 说明&#xff1a; 子组件类型&#xff1a;系统组件和自定义组件&#xf…

移动云行动:5.5G技术引领数字化转型

刚刚结束的全国两会上&#xff0c;有人大代表建议应尽快发挥5G-A&#xff08;5.5G&#xff09;优势&#xff0c;加快试点城市布局。此前&#xff0c;中国移动已宣布将在300多个城市启动5.5G商用部署。在通信技术的历史长河中&#xff0c;4G改变了我们的生活方式&#xff0c;而5…