【LeetCode算法系列题解】第6~10题

CONTENTS

    • LeetCode 6. N 字形变换(中等)
    • LeetCode 7. 整数反转(中等)
    • LeetCode 8. 字符串转换整数-atoi(中等)
    • LeetCode 9. 回文数(简单)
    • LeetCode 10. 正则表达式匹配(困难)

LeetCode 6. N 字形变换(中等)

【题目描述】

将一个给定字符串 s 根据给定的行数 numRows,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:

P   A   H   N
A P L S I I G
Y   I   R

之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"
请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);

【示例1】

输入:s = "PAYPALISHIRING", numRows = 3
输出:"PAHNAPLSIIGYIR"

【示例2】

输入:s = "PAYPALISHIRING", numRows = 4
输出:"PINALSIGYAHRPI"
解释:
P     I    N
A   L S  I G
Y A   H R
P     I

【示例3】

输入:s = "A", numRows = 1
输出:"A"

【提示】

1 ≤ s . l e n g t h ≤ 1000 1\le s.length\le 1000 1s.length1000
1 ≤ n u m R o w s ≤ 1000 1\le numRows\le 1000 1numRows1000
s 由英文字母(小写和大写)、',''.' 组成

【分析】


在这里插入图片描述

如上图所示,我们用数字来观察规律,设行数为 n n n

首先看第一行,0到6一共间隔 2 n − 2 2n-2 2n2 个数,因为从0走到3有 n − 1 n-1 n1 个数,3走到6也有 n − 1 n-1 n1 个数,因此第一行为从0开始的公差为 2 n − 2 2n-2 2n2 的等差数列。同理最后一行为从 n − 1 n-1 n1 开始的公差为 2 n − 2 2n-2 2n2 的等差数列。

对于中间行,以第二行为例,由两个等差数列组成,一个是在直线上的数列:1、7、13,这是从1开始的公差为 2 n − 2 2n-2 2n2 的等差数列;还有一个是在斜线上的数列:5、11、17,这是从5(可以看成 2 n − 2 − i 2n-2-i 2n2i i i i 表示这一行的第一个数)开始的公差为 2 n − 2 2n-2 2n2 的等差数列。因此中间行就是先输出第一个等差数列的第一项,然后输出第二个等差数列的第一项,再输出第一个等差数列的第二项,以此类推。


【代码】

class Solution {
public:string convert(string s, int n) {if (n == 1) return s;  // 特判string res;for (int i = 0; i < n; i++){if (i == 0 || i == n - 1)  // 第一行或最后一行for (int j = i; j < s.size(); j += 2 * n - 2)res += s[j];else// j表示第一个等差数列,k表示第二个等差数列for (int j = i, k = 2 * n - 2 - i; j < s.size() || k < s.size(); j += 2 * n - 2, k += 2 * n - 2){if (j < s.size()) res += s[j];if (k < s.size()) res += s[k];}}return res;}
};

LeetCode 7. 整数反转(中等)

【题目描述】

给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [ − 2 31 , 2 31 − 1 ] [-2^{31}, 2^{31} - 1] [231,2311],就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。

【示例1】

输入:x = 123
输出:321

【示例2】

输入:x = -123
输出:-321

【示例3】

输入:x = 120
输出:21

【示例4】

输入:x = 0
输出:0

【提示】

− 2 31 ≤ x ≤ 2 31 − 1 -2^{31}\le x\le 2^{31} - 1 231x2311

【分析】


首先有个小 Tips:C++中负数取模的结果也为负数,如 − 1234 % 10 = − 4 -1234\% 10=-4 1234%10=4

直接用 x % 10 x\% 10 x%10 求出 x x x 的个位数 a a a,然后 r e s = r e s ∗ 10 + a res=res*10+a res=res10+a,根据负数取模的特性易知该方式同样适用于负数。

注意我们当做无法使用 long long 类型,因此做溢出判断的时候需要对判断公式做一个变换。


【代码】

class Solution {
public:int reverse(int x) {int res = 0;while (x){// res * 10 + x % 10 > MAX -> res > (MAX - x % 10) / 10if (res > 0 && res > (INT_MAX - x % 10) / 10) return 0;if (res < 0 && res < (INT_MIN - x % 10) / 10) return 0;res = res * 10 + x % 10;  // x不管正负都通用x /= 10;}return res;}
};

LeetCode 8. 字符串转换整数-atoi(中等)

【题目描述】

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

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

注意:

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

【示例1】

输入:s = "42"
输出:42

【示例2】

输入:s = "   -42"
输出:-42

【示例3】

输入:s = "4193 with words"
输出:4193

【提示】

0 ≤ s . l e n g t h ≤ 200 0\le s.length\le 200 0s.length200
s 由英文字母(大写和小写)、数字(0-9)、' ''+''-''.' 组成

【分析】


模拟处理字符串即可,判断溢出的方式与上一题相似,唯一的一个坑点是负数的最小值的绝对值是比正数的最大值多1的,因此当恰好等于最小值时 r e s res res 存不下对应的正数,因此需要直接返回最小值。


【代码】

class Solution {
public:int myAtoi(string s) {int idx = 0;while (idx < s.size() && s[idx] == ' ') idx++;  // 过滤前导空格int op = 1;  // 标记正负,没有正负号时默认为正if (s[idx] == '-') op *= -1, idx++;else if (s[idx] == '+') idx++;int res = 0;while (idx < s.size() && s[idx] >= '0' && s[idx] <= '9'){int x = s[idx] - '0';// res * 10 + x > MAX -> res > (MAX - x) / 10if (op > 0 && res > (INT_MAX - x) / 10) return INT_MAX;// -res * 10 - x < MIN -> -res < (MIN + x) / 10if (op < 0 && -res < (INT_MIN + x) / 10) return INT_MIN;if (-res * 10 - x == INT_MIN) return INT_MIN;  // 特判刚好等于最小值res = res * 10 + x;idx++;}return res * op;}
};

LeetCode 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 -2^{31}\le x\le 2^{31} - 1 231x2311

【分析】


简单题,可以转换成字符串来做,也可以使用数值方法来做,用之前的方法逐步将 x x x 的个位取出来构建出新的数,然后判断两数是否相等即可。


【代码】

【字符串解法】

class Solution {
public:bool isPalindrome(int x) {if (x < 0) return false;  // 负数一定不是回文数string s = to_string(x);return s == string(s.rbegin(), s.rend());}
};

【数值解法】

class Solution {
public:bool isPalindrome(int x) {if (x < 0) return false;  // 负数一定不是回文数long long res = 0;  // 1234567899之类的数翻转后会溢出intint tmp = x;while (tmp) res = res * 10 + tmp % 10, tmp /= 10;return res == x;}
};

LeetCode 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 . l e n g t h ≤ 20 1\le s.length\le 20 1s.length20
1 ≤ p . l e n g t h ≤ 20 1\le p.length\le 20 1p.length20
s 只包含从 a-z 的小写字母
p 只包含从 a-z 的小写字母,以及字符 .*
保证每次出现字符 * 时,前面都匹配到有效的字符

【分析】


这题很难想到是 DP 问题,因此难度不小。我们一步步分析状态表示和状态计算:

  • 状态表示 f [ i ] [ j ] f[i][j] f[i][j]
    • 集合:所有 s [ 1 ∼ i ] s[1\sim i] s[1i] p [ 1 ∼ j ] p[1\sim j] p[1j](下标从1开始)的匹配方案。
    • 属性:bool 类型,表示是否存在一个合法方案。
  • 状态计算:
    • p [ j ] ≠ ∗ p[j]\ne * p[j]=,那么直接看 s [ i ] s[i] s[i] p [ j ] p[j] p[j] 是否匹配即可,若 s[i] == p[j] 或者 p[j] == '.',且满足 s s s 的前 i − 1 i-1 i1 个字符和 j j j 的前 j − 1 j-1 j1 个字符也匹配,那么 s [ i ] s[i] s[i] p [ j ] p[j] p[j] 匹配,即可以写出以下状态转移方程:
      f[i][j] = f[i - 1][j - 1] && (s[i] == p[j] || p[j] == '.')
    • p [ j ] = ∗ p[j]=* p[j]=,那么我们需要枚举一下 * 表示多少个字符,如果表示0个字符,则 s s s 的前 i i i 个字符和 j j j 的前 j − 2 j-2 j2 个字符匹配;如果表示1个字符,则 s s s 的前 i − 1 i-1 i1 个字符和 j j j 的前 j − 2 j-2 j2 个字符匹配,且 s[i] == p[j - 1];如果表示2个字符,则 s s s 的前 i − 2 i-2 i2 个字符和 j j j 的前 j − 2 j-2 j2 个字符匹配,且 s[i - 1] == p[j - 1] && s[i] == p[j - 1]。因此可以写出以下状态转移方程(没有将 p[j - 1] == '.' 写进去,别忘了这种情况也算匹配):
      f[i][j] = f[i][j - 2] || (f[i - 1][j - 2] && s[i] == p[j - 1]) || (f[i - 2][j - 2] && s[i - 1] == p[j - 1] && s[i] == p[j - 1]) ...
      现在我们进行优化,写出 f[i - 1][j] 的状态转移方程如下:
      f[i - 1][j] = f[i - 1][j - 2] || (f[i - 2][j - 2] && s[i - 1] == p[j - 1]) ...
      因此可以写出优化后的状态转移方程(将 p[j - 1] == '.' 考虑进去):
      f[i][j] = f[i][j - 2] || f[i - 1][j] && (s[i] == p[j - 1] || p[j - 1] == '*')

【代码】

class Solution {
public:bool isMatch(string s, string p) {int n = s.size(), m = p.size();s = ' ' + s, p = ' ' + p;  // 在首部加一个空格,因为我们要从第一位开始vector<vector<bool>> f(n + 1, vector<bool>(m + 1));f[0][0] = true;for (int i = 0; i <= n; i++)for (int j = 1; j <= m; j++)  // p为空肯定无法匹配,而s为空不一定{if (i && p[j] != '*')  // 注意i不能为0,因为需要使用f[i - 1]f[i][j] = f[i - 1][j - 1] && (s[i] == p[j] || p[j] == '.');else if (p[j] == '*')// 同样注意i不能为0f[i][j] = f[i][j - 2] || i && f[i - 1][j] && (s[i] == p[j - 1] || p[j - 1] == '.');}return f[n][m];}
};

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

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

相关文章

C# Linq源码分析之Take(四)

概要 本文主要对Take的优化方法进行源码分析&#xff0c;分析Take在配合Select&#xff0c;Where等常用的Linq扩展方法使用时候&#xff0c;如何实现优化处理。 本文涉及到Select, Where和Take和三个方法的源码分析&#xff0c;其中Select, Where, Take更详尽的源码分析&…

【日积月累】后端刷题日志

刷题日志 说说对Java的理解JAVA中抽象类和接口之间的区别Java中的泛型 和equals()的区别八种基本数据类型与他们的包装类在一个静态方法内调用一个非静态成员为什么是非法的静态方法与实例方法有何不同重载与重写深拷贝浅拷贝面向过程与面向对象成员变量与局部变量Spring框架Sp…

Spring Bean对象生命周期

文章目录 前言基础通俗理解bean作用域 前言 最近学习spring的一些基础概念&#xff0c;所以就先了解了bean对象的概念&#xff0c;而且发现这个里面涉及到很多的内容&#xff0c;比如在spring中一个bean对象是如何创建以及销毁的这些概念&#xff0c;所以就打算总结一些spring…

微信开发之一键踢出群聊的技术实现

简要描述&#xff1a; 删除群成员 请求URL&#xff1a; http://域名地址/deleteChatRoomMember 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参数名必选…

SpringBoot之logback-spring.xml详细配置

《logback官网》 各种指导文件&#xff0c;有空自己去看&#xff0c;比如&#xff1a;我们需要调整的是布局&#xff0c;直接看Layouts。 pom.xml <!-- 环境配置 --><profiles><profile><id>dev</id><properties><spring.profiles.a…

基于java swing和mysql实现的汽车租赁管理系统(源码+数据库+文档+运行指导视频)

一、项目简介 本项目是一套基于java swing和mysql实现的汽车租赁管理系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、项目文档、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经…

麒麟系统上安装 MySQL 8.0.24

我介绍一下在麒麟系统上安装 MySQL 8.0.24 的详细步骤&#xff0c;前提是您已经下载了 mysql-8.0.24-linux-glibc2.12-x86_64.tar.xz 安装包。其实安装很简单&#xff0c;但是有坑&#xff0c;而且问题非常严重&#xff01;由于麒麟系统相关文章博客较少&#xff0c;导致遇到了…

java八股文面试[数据库]——MySql聚簇索引和非聚簇索引区别

聚集索引和非聚集索引 聚集索引和非聚集索引的根本区别是表记录的排列顺序和与索引的排列顺序是否一致。 1、聚集索引 聚集索引表记录的排列顺序和索引的排列顺序一致&#xff08;以InnoDB聚集索引的主键索引来说&#xff0c;叶子节点中存储的就是行数据&#xff0c;行数据在…

MFC -- Date Time Picker 控件使用

当前环境&#xff1a;VS2015 Windows 10 //&#xff08;一&#xff09;使用普通函数&#xff0c; 获取当前时间CString strCurrentTime; COleDateTime m_time COleDateTime::GetCurrentTime(); strCurrentTime m_time.Format(_T("%Y-%m-%d %H:%M:%S")); SetDlgIt…

【python爬虫案例】用python爬豆瓣读书TOP250排行榜!

文章目录 一、爬虫对象-豆瓣读书TOP250二、python爬虫代码讲解三、讲解视频四、完整源码 一、爬虫对象-豆瓣读书TOP250 您好&#xff0c;我是 马哥python说 &#xff0c;一名10年程序猿。 今天我们分享一期python爬虫案例讲解。爬取对象是&#xff0c;豆瓣读书TOP250排行榜数…

使用这个插件,fiddler抓包直接生成httprunner脚本

har2case可以将.har文件转化成yaml格式或者json格式的httprunner的脚本文件&#xff0c;生成.har格式文件可以借助 fiddler 或 Charles 抓包工具 友情提示&#xff1a; 录制脚本&#xff0c;只是一个过渡&#xff0c;从0到1的一个过渡&#xff0c;如果让你直接写脚本&#xf…

xsschallenge通关(1-10)

文章目录 level1level 2level 3level 4level 5level 6level 7level 8level9level 10 level1 这一关很简单&#xff0c;标准的xss注入&#xff0c;打开hackbar&#xff0c;输入 <script>alert(/xss/)</script>点击EXECUTE&#xff0c;通关&#xff01; level 2 这…

设计模式之命令模式(Command)的C++实现

1、命令模式的提出 在软件开发过程中&#xff0c;“行为请求者”和“行为实现者”通常呈现一种“紧耦合”&#xff0c;如果行为的实现经常变化&#xff0c;则不利于代码的维护。命令模式可以将行为的请求者和行为的实现者进行解耦。具体流程是将行为请求者封装成一个对象&…

python基础爬虫反爬破解

文章目录 爬虫初识1. HTTP协议与WEB开发&#xff08;1&#xff09;简介&#xff08;2&#xff09;socket套接字&#xff08;3&#xff09;请求协议与响应协议 2. requests&反爬破解&#xff08;1&#xff09;UA反爬&#xff08;2&#xff09;referer反爬&#xff08;3&…

基于Java+SpringBoot+Vue前后端分离客户关系管理系统设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

电子词典dictionary

一、项目要求&#xff1a; 1.登录注册功能&#xff0c;不能重复登录&#xff0c;重复注册。用户信息也存储在数据库中。 2.单词查询功能 3.历史记录功能&#xff0c;存储单词&#xff0c;意思&#xff0c;以及查询时间&#xff0c;存储在数据库 4.基于TCP&#xff0c;支持多客户…

Skip Connection——提高深度神经网络性能的利器

可以参考一下这篇知乎所讲 https://zhuanlan.zhihu.com/p/457590578 长跳跃连接用于将信息从编码器传播到解码器&#xff0c;以恢复在下采样期间丢失的信息

TCP/UDP原理

文章目录 一、端口1. 端口的定义和作用2.服务端和客户端的区别3.常见的知名端口号有 二、TCP的原理1.TCP头部封装格式2.TCP可靠性机制三次握手确认机制四次挥手RST结束连接窗口机制 3.完整性校验4.TCP特征5.TCP的适用场景 三、UDP的原理1.UDP头部封装格式2.UDP特征3.UDP的适用场…

微信小程序云开发-云存储文件ID转http

一、前言 云开发的云储存文件默认是以cloudID的形式读取的&#xff0c;但是这种读取方式只能在微信小程序或内嵌H5中使用。 所以如果需要在其他地方使用&#xff0c;例如浏览器或网站等其他端读取文件的时候&#xff0c;需要转换成普通的http链接。 目前官方提供有转换的接口…

Android View动画整理

View 动画相关内容可参考官网 动画资源 此前也有写 View 动画相关的内容&#xff0c;但都只是记录代码&#xff0c;没有特别分析。以此篇作为汇总、整理、分析。 Android View 动画有4中&#xff0c;分别是 平移动画 TranslateAnimation缩放动画 ScaleAnimation旋转动画 Rot…