整数反转/回文 : 整数取模运算,(转化为字符串后)双指针向中间走
lc 7
整数转化为字符串
判断给定整数x的正负情况,把符号提取出来,然后将 abs(x) 变成字符串,将字符串反转,最后再恢复成整数
class Solution(object):
def reverse(self, x):
string = str(abs(x))
ans = int(string[::-1])
if x > 0:
return ans if ans <= (1<<31)-1 else 0
if x < 0:
return -ans if -ans >= -(1<<31) else 0
return 0
整数取模运算
Python的坑: 由于Python的 // 操作是向下取整,导致正负数取余 % 操作结果不一致,因此需要将原数字转为正数操作。
1.循环弹出输入整数x的最后一位,累加至新整数y
2.根据x的正负还原整数y的符号
3.输出整数y范围应为 [−2^31, 2^31 − 1](可用位运算),若溢出,返回 0,若不溢出,返回整数y
4.可在循环过程中判断是否溢出,提前终止
class Solution:
def reverse(self, x: int) -> int:
y, res = abs(x), 0
of = (1 << 31) - 1 if x > 0 else 1 << 31
while y != 0:
res = res * 10 + y % 10
if res > of: return 0
y //= 10
lc 8
正则表达式
通用做法
总结一下整个执行流程:
- 过滤掉前面若干个空格(如果有的话)
- 判断正号、负号位,如果是负号则记录下状态,表示输入的是负数。
- 循环判断后面的字符串是否是0到9,如果是则累加这个值
while i < n and str[i] >= '0' and str[i] <= '9':
tmp = ord(str[i]) - ord('0') # 将字符转化为数字
- 当前的值跟最大、最小32位整数比较看是否溢出,计算 2^31可用位运算
- 循环结束后,根据负号的标志位返回对应的正数或负数
class Solution(object):
def myAtoi(self, str):
if not str: return 0
i, n = 0, len(str)
# 跳过开头的所有空格
while i < n and str[i] == ' ':
i += 1
# 如果字符串全是空格,返回0
if i == n:
return 0
# 如果第一个非空的位置是符号,记录符号,并且 i 前进一位
neg = True if str[i] == '-' else False
if str[i] in ('+','-'): i += 1
# 这里使用了 in 运算符
# 循环判断字符是否在 0~9之间
res = 0
while i < n and str[i] >= '0' and str[i] <= '9':
# '0'的ASCII码是48,'1'的是49,这么一减就从就可以得到真正的整数值
tmp = ord(str[i]) - ord('0')
res = res * 10 + tmp
if not neg and res >= (1<<31)-1:
return (1<<31)-1
elif neg and -res <= -(1<<31):
return -(1<<31)
i += 1
# 如果有负号标记则返回负数
return -res if neg else res
lc 9
特殊情况直接 return False:
1.负数
2.100 / 2000 / … 非0的整十百千数字
整数转化为字符串
整数必须转化为字符串才可以使用 len() 和指针
class Solution(object):
def isPalindrome(self, x):
"""
:type x: int
:rtype: bool
"""
## 整数转化为字符串才可以len()以及指针
x = str(x)
n = len(x)
j = n-1
for i in range(n/2):
if x[i] == x[j]:
j -= 1
else:
return False
return True
或者利用python内置函数
class Solution(object):
def isPalindrome(self, x):
return str(x)==str(x)[::-1]
整数反转:取模运算
class Solution(object):
def isPalindrome(self, x):
if x<0:
return False
ans, old = 0, x
while x>0:
tmp = x%10
ans = ans*10 + tmp
x //= 10
return ans==old
整数反转一半
利用【回文】的对称性:不用反转整数的所有数字,只需要反转一半数字就可以了。
反转一半数字的循环终止条件:可以根据数字的长度(一半)来判断,但是又不想遍历求长度,可以发现,对于奇数长度的回文数字12321,我们可以拆分成两个数12和123,对于偶数长度的回文数字123321,我们可以拆分成两个数字123和123。
即,如果回文数长度为奇数,经过循环处理,新数字正好是原数字x的10倍,如果长度为偶数,新数字恰好等于原数字。
或者,直接用大于来判断,原数字如果小于新数字则退出循环。
class Solution(object):
def isPalindrome(self, x):
if x<0 or (x%10==0 and x!=0):
return False
ans = 0
while x>ans:
ans = ans*10 + x%10
x //= 10
return x==ans or x==(ans//10)