【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 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,点击下方名片关注我。☟

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

防范服务器被攻击:查询IP地址的重要性与方法

在当今数字化时代&#xff0c;服务器扮演着重要的角色&#xff0c;为企业、组织和个人提供各种网络服务。然而&#xff0c;服务器也成为了网络攻击者的目标之一&#xff0c;可能面临各种安全威胁&#xff0c;例如DDoS攻击、恶意软件攻击、数据泄露等。为了有效地防范服务器被攻…

C语言基础之结构体

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

pytorch升级打怪(三)

数据集合数据加载器 简介加载数据集迭代和可视化数据集为您的文件创建自定义数据集__init____len____getitem__ 准备您的数据以使用DataLoaders进行训练通过DataLoader进行遍载 简介 处理数据样本的代码可能会变得混乱且难以维护&#xff1b;理想情况下&#xff0c;我们希望我…

软考高级:企业应用集成概念和例题

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

内网渗透之路:常用命令助力信息深度探索

1、查询网络配置信息 ipconfig /all 2、查询操作系统及软件信息 &#xff08;1&#xff09;查询操作系统和版本信息 英文操作系统 systeminfo | findstr /B /C:"OS Name" /C:"OS Version" 中文操作系统 systeminfo | findstr /B /C:"OS 名称&q…

论文阅读:FCB-SwinV2 Transformer for Polyp Segmentation

这是对FCBFormer的改进&#xff0c;我的关于FCBFormer的论文阅读笔记&#xff1a;论文阅读FCN-Transformer Feature Fusion for PolypSegmentation-CSDN博客 1&#xff0c;整体结构 依然是一个双分支结构&#xff0c;总体结构如下&#xff1a; 其中一个是全卷积分支&#xff…

【Flutter 面试题】什么是Widget,Stateful Widget和Stateless Widget之间的区别?

【Flutter 面试题】什么是Widget&#xff0c;Stateful Widget和Stateless Widget之间的区别&#xff1f; 文章目录 写在前面解答补充说明StatelessWidget 示例StatefulWidget 示例 写在前面 &#x1f64b; 关于我 &#xff0c;小雨青年 &#x1f449; CSDN博客专家&#xff0c…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:TextArea)

多行文本输入框组件&#xff0c;当输入的文本内容超过组件宽度时会自动换行显示。 高度未设置时&#xff0c;组件无默认高度&#xff0c;自适应内容高度。宽度未设置时&#xff0c;默认撑满最大宽度。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&…

会员项目定价卡css3特效

会员项目定价卡css3特效&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面 下载地址 会员项目定价卡css3特效代码

WIFI 7技术的应用前景

随着WIFI 7技术的不断成熟和普及&#xff08;如果对WIFI 7技术不太了解的&#xff0c;可以点击链接去查看一下这篇文章WIFI7&#xff1a;开启无线通信新纪元 &#xff09;&#xff0c;我们正迎来一个数字连接的全新时代。WIFI 7作为新一代无线网络标准&#xff0c;将极大的改变…

【矩阵】48. 旋转图像【中等】

旋转图像 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《适应分布式资源渗透率提高的配电网网元规划方法》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

springboot276基于JS的个人云盘管理系统的设计与实现

个人云盘管理系统设计与实现 摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装个人云盘管理系统软件来发挥其…

了解常用测试模型 -- V模型、W模型

目录 V模型 测试流程 特点 优、缺点 w模型/双v模型 测试流程 特点 优、缺点 V模型 测试流程 用户需求&#xff1a;产品经理将用户需求转变为软件需求 需求分析与系统设计&#xff1a;验证需求是否正确&#xff0c;确定编程语言和框架 概要设计&#xff1a;项目结构设…

大语言模型系列-中文开源大模型

文章目录 前言一、主流开源大模型二、中文开源大模型排行榜 前言 近期&#xff0c;OpenAI 的主要竞争者 Anthropic 推出了他们的新一代大型语言模型 Claude 3&#xff0c;该系列涵盖了三个不同规模的模型&#xff1a;Opus、Sonnet 和 Haiku。 Claude 3声称已经全面超越GPT-4。…

Antd组件Input在暗黑模式下,autoComplete导致的背景色问题

Antd的组件暗黑模式&#xff0c;默认Input的背景色是暗黑的&#xff0c;但是浏览器支持自动填充功能的话&#xff0c;就会变成这样&#xff0c;看着就难受 两种解决方法&#xff1a; 一、关闭自动填充功能 <Input autoComplete"off" /> 二、添加样式&#x…

使用 ZipArchiveInputStream 读取压缩包内文件总数

读取压缩包内文件总数 简介 ZipArchiveInputStream 是 Apache Commons Compress 库中的一个类&#xff0c;用于读取 ZIP 格式的压缩文件。在处理 ZIP 文件时&#xff0c;编码格式是一个重要的问题&#xff0c;因为它决定了如何解释文件中的字符数据。通常情况下&#xff0c;Z…

[.NET项目实战] Elsa开源工作流组件应用(一): Elsa工作流简介

Elsa工作流简介 工作流是什么&#xff1f; 引用维基百科中对工作流的解释&#xff1a; 是对工作流程及其各操作步骤之间业务规则的抽象、概括、描述。工作流建模&#xff0c;即将工作流程中的工作如何前后组织在一起的逻辑和规则在计算机中以恰当的模型进行表示并对其实施计算…

考研模拟面试-答案【攻略】

考研模拟面试-答案【攻略】 前言版权推荐考研模拟面试-答案前面的问题通用问题专业题数据结构计算机网络操作系统数据库网络安全 手写题数据结构操作系统计算机网络 代码题基础代码题其他代码题 后面的问题补充题目 基础代码题答案链栈循环队列1循环队列2哈希表 最后 前言 202…

软件测试 —— 案例系统缺陷报告

知识&#xff1a; 1、缺陷等级&#xff1a; 1-Urgent(致命错误)&#xff1a;影响全局的死机、通信中断、重要业务不能完成 2-Very High(严重错误)&#xff1a;规定的功能没有实现或不完整或产生错误结果&#xff1b;使系统不稳定、或破坏数据等 3-High(一般错误)&#xff1a;…