[ LeetCode ] 题刷刷(Python)-第9题:回文数

文章介绍了两种方法判断给定整数是否为回文数:一是通过转化为字符串并反向切片;二是直接对整数进行数学操作。分析了这两种方法的时间复杂度均为O(n),空间复杂度分别为O(n)和O(1)。
摘要由CSDN通过智能技术生成

题目描述

给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。

回文数
是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

例如,121 是回文,而 123 不是。

示例

示例 1:

输入:x = 121
输出:true
示例 2:

输入:x = -121
输出:false
解释:从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例 3:

输入:x = 10
输出:false
解释:从右向左读, 为 01 。因此它不是一个回文数。

解题

解法一: 转化为字符串反向切片

思路

把整数转换成字符串,然后进行反向切片,从而实现了反转。最后再比对是否相等,即可。

算法复杂度

时间复杂度:O(n),其中 n 是输入整数 x 的位数。

转换为字符串的时间复杂度大致为 O(n),因为需要遍历每一位并将其转换为字符。

获取反向字符串的时间复杂度也为 O(n)。

比较字符串是否相等:时间复杂度为 O(1)。

综上所述:根据加法法则,总的时间复杂度等于各步骤中最耗时的部分,即 O(n)。因此,该实现的时间复杂度为 O(n),其中 n 是输入整数 x 的位数。


空间复杂度:O(n),其中 n 是输入整数 x 的位数。

字符串存储:在将整数 x 转换为字符串时,需要创建一个新的字符串对象来存储转换结果。字符串的长度与整数 x 的位数相同,即 n。因此,这部分的空间复杂度为 O(n)。

反向字符串:这部分的空间复杂度为 O(1)。

综上所述:故该实现的空间复杂度为 O(n),其中 n 是输入整数 x 的位数。

代码
class Solution:
    def isPalindrome(self, x: int) -> bool:
        return str(x)==str(x)[::-1]

解法二:直接对整数进行数学操作

思路

循环逐个取出整数的低位数字,并添加到反转部分 reversed_part 中,直到处理完整数x,然后再比对reversed_part是否与整数x相等。

利用:%10来取原始整数的最低位,//10 去掉原始整数已处理的最低位数字。

算法复杂度

时间复杂度:O(n),其中 n 是输入整数 x 的位数。

整个函数的时间复杂度主要由循环决定,为 O(n),其中 n 是输入整数 x 的位数。


空间复杂度:O(1),常数空间存放若干变量。

代码
class Solution:
    def isPalindrome(self, x: int) -> bool:
        
        # 如果是负数,肯定不是回文数,直接返回False
        if x < 0:
            return False

        # 初始化反转部分
        reversed_part = 0

        # 用于存储原始整数除以10后的余数
        original_num = x

        while original_num > 0:
            remainder = original_num % 10  # 取出最低位
            # 实现最先取出的最低位,始终排在前面
            reversed_part = (reversed_part * 10) + remainder
            original_num //= 10  # 去除掉已经取出的最低位

        # 反转结果是否等于原始整数
        return original_num == 0 and reversed_part == x
算法优化
思路

回文数,正序和逆序都是一样的,所以可以考虑只处理一半,可以进一步减少计算。

那么在此算法的基础上,如何确定处理了一半的整数呢?

假设当前原始数字是回文数的基础上,当原始整数小于或等于反转后的数字时,就是已经处理到一半了。

如果该原始整数不是回文数,利用上面说的条件,有可能会多处理,不是处理一半,但是这个不是重点,例如:如果是5423,最后就是return 5==324 or 5==32。因为多处理了,最后剩余的原始整数和反转的结果肯定也没法相等。

在判断为负数的基础上还可以进一步筛选处理无效的数字:如果该整数不是0,而最低位为0。那也不是回文数,因为第一位数字不会是0。

算法复杂度

时间复杂度: O(n),其中 n 是输入整数 x 的位数。

对于偶数位整数,循环次数接近一半;对于奇数位整数,循环次数略大于一半。总体来看,循环次数大致为整数位数的一半,因此时间复杂度还是为 O(n),其中 n 是输入整数 x 的位数。


空间复杂度:O(1),常数空间存放若干变量。

代码 
class Solution:
    def isPalindrome(self, x: int) -> bool:
        # 如果是负数,肯定不是回文数,直接返回False
        # 个位为0但本身不是0的数,因为第一位数不会是0,而最后一位数为0,肯定不是回文数
        if x < 0 or (x != 0 and x % 10 == 0): 
            return False

        # 初始化反转部分
        reversed_part = 0

        # 用于存储原始整数除以 10 后的余数
        original_num = x

        # 假设原始数字是回文数的基础上
        # 当原始数字大于反转后的数字时,说明还没有处理到一半
        while original_num > reversed_part:
            remainder = original_num % 10
            reversed_part = (reversed_part * 10) + remainder
            original_num //= 10

        # 如果整数是偶数位,则反转结果刚好可以等于原始整数数剩下的一半
        # 如果是奇数,反转结果会比原始整数剩下的一半多一位,所以反转结果在比较时要再去除掉一位
        return original_num == reversed_part or original_num == reversed_part // 10
注意事项 

上述优化的代码,在进行反转一半处理前,一定要先排除待判断整数的个位为0的情况(x != 0 and x % 10 == 0),不然在处理最低位为0的情况下,会出错误哦~~~

  • 24
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我好想敲代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值