当前位置: 首页 > article >正文

LeetCode【0009】回文数

本文目录

  • 1 中文题目
  • 2 求解思路
    • 2.1 基础解法:数字反转法
    • 2.2 优化解法: 双指针数学法
    • 2.3 最优解法:取一半数字法
  • 3 题目总结

1 中文题目

给你一个整数 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} \leq x \leq2^{31} - 1 231x2311

2 求解思路

2.1 基础解法:数字反转法

思路
将整个数字反转后与原数字比较,如果相等则为回文数。需要注意负数不可能是回文数,并且要处理反转时可能的整数溢出问题。

Python代码

class Solution:
    def isPalindrome(self, x: int) -> bool:
        """
        判断一个整数是否是回文数
        
        参数:
            x: 输入的整数
            
        返回:
            布尔值,表示是否是回文数
        """
        # 处理负数和以0结尾的非0数
        # 负数不可能是回文数
        # 除0以外,以0结尾的数不可能是回文数
        if x < 0 or (x != 0 and x % 10 == 0):
            return False
            
        # 处理0-9的个位数
        if x < 10:
            return True
            
        # 反转整个数字
        original = x
        reversed_num = 0
        
        # 逐位反转数字
        while x > 0:
            # 获取最后一位数字
            digit = x % 10
            
            # 处理溢出情况
            # Python不需要处理溢出,但如果在其他语言中需要处理
            if reversed_num > 214748364:  # 2^31-1 = 2147483647
                return False
                
            # 构建反转后的数字
            reversed_num = reversed_num * 10 + digit
            
            # 去掉原数字的最后一位
            x //= 10
            
        # 比较原数字和反转后的数字是否相等
        return original == reversed_num

时空复杂度分析

  • 时间复杂度分析 O(log n)
    • 需要遍历数字的每一位
    • n的位数大约是log10(n)
  • 空间复杂度分析 O(1)
    • 只使用了几个变量
    • 不需要额外的数据结构

2.2 优化解法: 双指针数学法

思路
通过数学运算获取数字的最高位和最低位(不转换为字符串),从两端向中间比较。使用除法获取最高位,取模获取最低位,每次比较后通过数学运算去除首尾数字,继续比较剩余部分,直到处理完所有位数。

python代码

class Solution:
    # 直接使用除法和取模
    def isPalindrome(self, x: int) -> bool:
        """
        使用除法和取模的方式实现双指针比较
        """
        # 处理负数和以0结尾的非0数
        if x < 0 or (x != 0 and x % 10 == 0):
            return False
            
        # 计算除数(用于获取最高位)
        div = 1
        while x // div >= 10:
            div *= 10
            
        # 从两端向中间比较
        while x > 0:
            # 获取最高位和最低位
            left = x // div
            right = x % 10
            
            # 比较最高位和最低位
            if left != right:
                return False
                
            # 去掉最高位和最低位
            x = (x % div) // 10
            # 除数要减少两位
            div //= 100
            
        return True

时空复杂度分析

  • 时间复杂度分析 O ( l o g n ) O(log n) O(logn)
    • 计算位数需要 O ( l o g n ) O(log n) O(logn)
    • 比较过程需要 O ( l o g n ) O(log n) O(logn)
  • 空间复杂度分析 O ( 1 ) O(1) O(1)
    • 只使用了固定数量的变量
    • 不需要额外的数据结构

2.3 最优解法:取一半数字法

思路
将数字后半部分反转,只需要一个简单的判断条件就能同时处理奇数位和偶数位的情况。当原数等于反转数 或 原数等于反转数去掉最后一位时,就是回文数。

算法步骤举例:

  • 对于偶数位数字1221:
x=1221, reversed_num=0
x=122, reversed_num=1
x=12, reversed_num=12
12 == 12 为true
  • 对于奇数位数字12321:
x=12321, reversed_num=0
x=1232, reversed_num=1
x=123, reversed_num=12
x=12, reversed_num=123
12 == 123//10 为true

python代码

class Solution:
    def isPalindrome(self, x: int) -> bool:
        """
        取一半数字法的简洁实现
        
        参数:
            x: 输入的整数
            
        返回:
            布尔值,表示是否是回文数
        """
        # 处理特殊情况:负数和以0结尾的非0数
        if x < 0 or (x != 0 and x % 10 == 0):
            return False
            
        # reversed_num存储反转后的后半部分数字
        reversed_num = 0
        
        # 当原始数字大于反转数字时继续处理
        # 这确保我们只处理后半部分数字
        while x > reversed_num:
            # 取出x的最后一位,加入到反转数字中
            reversed_num = reversed_num * 10 + x % 10
            # 去掉x的最后一位
            x //= 10
            
        # 统一处理奇数位和偶数位的情况:
        # 偶数位:x == reversed_num (例如:1221)
        # 奇数位:x == reversed_num//10 (例如:12321)
        return x == reversed_num or x == reversed_num // 10

时空复杂度分析

  • 时间复杂度:O(log n)
    • 只处理数字的一半位数
    • 每次操作是常数时间
  • 空间复杂度:O(1)

3 题目总结

题目难度:简单
应用算法:双指针、数学计算


http://www.kler.cn/a/393592.html

相关文章:

  • 【自用】0-1背包问题与完全背包问题的Java实现
  • 从社交媒体到元宇宙:Facebook未来发展新方向
  • Bugku CTF_Web——文件上传
  • Spring MVC 与 JSP 数据传输
  • 6.2 对角化矩阵(2)
  • Qt 获取当前系统中连接的所有USB设备的信息 libudev版
  • 微信小程序=》基础=》常见问题=》性能总结
  • 期货配资系统行情源对接通讯协议范本
  • 如何选择适合小团队的项目管理工具?免费与开源软件推荐
  • cache中命中率和平均访问时间
  • odoo 17 后端路由接口认证自定义
  • 前端常用布局模板39套,纯CSS实现布局
  • Python 虚拟环境创建
  • Linux解决 -bash: nc: command not found-bash: nc: 未找到命令
  • hive的tblproperties支持修改的属性
  • QT自定义控件封装
  • axios三层封装
  • Java应用线上问题排查指南
  • 16008.行为树(五)-自定义数据指针在黑板中的传递
  • 深入理解 React 架构从概览到核心机制
  • redis 原理篇 28 通信协议 RESP协议
  • LeetCode40:组合总和II
  • SpringBoot集成itext导出PDF
  • i春秋-GetFlag(HTTP请求方法使用,XXF伪造ip)
  • Redis四种架构模式
  • 大模型时代,呼叫中心部门如何建设一套呼出机器人系统?