本篇为Datawhale组队学习计划第21期LeetCode精选题目组Task01学习笔记。
初学,时间有点仓促,很多解法没有详细分析,未来会修改,见谅。
所有题目均参考了Datawhale学习文档,开源地址:
https://github.com/datawhalechina/team-learning-program/tree/master/LeetCodeTencent
007 整数反转
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-integer
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
注意:
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−2^31, 2^31 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。
示例
输入:x = 123,输出:321
输入:x = -123,输出:-321
输入:x = 120,输出:21
输入:x = 0,输出:0
思路
本题主要考虑溢出的问题。主要思路参考:
https://leetcode-cn.com/problems/reverse-integer/solution/zheng-shu-fan-zhuan-by-leetcode/(官方题解,方法:弹出和推入数字 & 溢出前进行检查)
https://leetcode-cn.com/problems/reverse-integer/solution/tu-jie-7-zheng-shu-fan-zhuan-by-wang_ni_ma/
第二个方法比较好理解,就是不断取模,取到末尾数字,每次判断是否溢出。
Python实现
class Solution:
def reverse(self, x: int) -> int:
res = 0
x1 = abs(x)
while(x1!=0):
temp = x1%10 # 取末尾数字
if res > 214748364 or (res==214748364 and temp>7):
return 0 # 判断溢出
if res<-214748364 or (res==-214748364 and temp<-8):
return 0
res = res*10 +temp
x1 //=10 # 地板除,得到整数
return res if x >0 else -res
008 字符串转换整数(atoi)
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/string-to-integer-atoi
请你来实现一个 atoi 函数,使其能将字符串转换成整数。
首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。接下来的转化规则如下:
- 如果第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字字符组合起来,形成一个有符号整数。
- 假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成一个整数。
- 该字符串在有效的整数部分之后也可能会存在多余的字符,那么这些字符可以被忽略,它们对函数不应该造成影响。
- 假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换,即无法进行有效转换。
- 在任何情况下,若函数不能进行有效的转换时,请返回 0 。
注意:
本题中的空白字符只包括空格字符 ’ ’ 。
假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−2^31, 2^31 − 1]。如果数值超过这个范围,请返回 2^31 − 1 或 −2^31 。
示例
输入: “42” 输出: 42
输入: " -42" 输出: -42(注意-42前有一个空格_)
解释: 第一个非空白字符为 ‘-’, 它是一个负号。
我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。
输入: “4193 with words”
输出: 4193
解释: 转换截止于数字 ‘3’ ,因为它的下一个字符不为数字。
输入: “words and 987”
输出: 0
解释: 第一个非空字符是 ‘w’, 但它不是数字或正、负号。
因此无法执行有效的转换。
输入: “-91283472332”
输出: -2147483648
解释: 数字 “-91283472332” 超过 32 位有符号整数范围。
因此返回 INT_MIN (−231) 。
提示:
0 <= s.length <= 200
s 由英文字母(大写和小写)、数字、’ ‘、’+’、’-’ 和 ‘.’ 组成
思路
参考题解:https://leetcode-cn.com/problems/string-to-integer-atoi/solution/python-1xing-zheng-ze-biao-da-shi-by-knifezhu/
主要用python的正则表达式:
^:匹配字符串开头
[+-]:代表一个+字符或-字符
?:前面一个字符可有可无
\d:一个数字
+:前面一个字符的一个或多个
\D:一个非数字字符
*:前面一个字符的0个或多个
max(min(数字, 2**31 - 1), -2**31) 防止越界
(顺便加一句刚学到的markdown排版时**加粗的部分**,可以加入\转义以正常显示*号)
实现
class Solution:
def myAtoi(self, s: str) -> int:
return max(min(int(*re.findall('^[\+\-]?\d+', s.lstrip())), 2**31 - 1), -2**31)
import re
class Solution:
def myAtoi(self, str: str) -> int:
INT_MAX = 2147483647
INT_MIN = -2147483648
str = str.lstrip() #清除左边多余的空格
num_re = re.compile(r'^[\+\-]?\d+') #设置正则规则
num = num_re.findall(str) #查找匹配的内容
num = int(*num) #由于返回的是个列表,解包并且转换成整数
return max(min(num,INT_MAX),INT_MIN) #返回值
009 回文数
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/palindrome-number
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
你能不将整数转为字符串来解决这个问题吗?
示例
输入: 121
输出: true
输入: -121
输出: false
解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
输入: 10
输出: false
解释: 从右向左读, 为 01 。因此它不是一个回文数。
思路
- 先排除一些情况:
所有负数都不可能是回文,
除了 0 以外,所有个位是 0 的数字不可能是回文,因为最高位不等于 0。
官方题解
-
题目要求不用字符串,可以考虑反复取模获取反转后的数字,再与原数字比较。
回文数13531为例,rN:1→13→135, x:1353→135。 -
判断条件:
while x > revertedNumber
由于整个过程我们不断将原始数字除以 10,然后给反转后的数字乘上 10,所以,当原始数字小于或等于反转后的数字时,就意味着我们已经处理了一半位数的数字了。
不管是不是回文数,反转数字位数大于等于n/2即可离开循环。
回文数13531, 判断到135=135,return 1;
非回文数654321,判断到123<654,下一次1234>65,return 0。
python实现
来源:https://leetcode-cn.com/problems/palindrome-number/solution/hui-wen-shu-by-leetcode-solution/436848
注释为笔者所加。
class Solution:
def isPalindrome(self, x: int) -> bool:
# 直接排除特殊情况
if x < 0 or (x % 10 == 0 and x != 0):
return False
revertedNumber = 0 # 反转后的数字
while x > revertedNumber:
revertedNumber = revertedNumber * 10 + x % 10
x //= 10 # 取整,取原数前n-1位
return x == revertedNumber or x == revertedNumber // 10
# 当数字长度为奇数时,通过 revertedNumber/10 去除处于中位的数字