回文数-leetCode-009

 

回文数是指正序(从左向右)和倒序(从右向左)读都相同的整数。例如,121 是回文数,而 -121 和 10 不是。本文将介绍两种解法:字符串转换法反转一半数字法,并分析它们的复杂度。


解法一:字符串转换法

思路

将整数转换为字符串,然后使用双指针从两端向中间比较字符是否相同。如果所有字符都相同,则是回文数;否则不是。

步骤
  1. 处理负数:负数直接返回 false(因为有负号)。

  2. 转换为字符串:将整数转为字符串。

  3. 双指针比较

    • 左指针从字符串头部开始,右指针从尾部开始。

    • 依次比较左右指针的字符,若不同则返回 false

    • 若所有字符相同,则返回 true

复杂度
  • 时间复杂度:O(n),其中 n 是数字的位数。需要遍历一半字符串。

  • 空间复杂度:O(n),存储字符串需要额外空间。

    class Solution {
        public boolean isPalindrome(int x) {
            // 负数直接返回 false
            if (x < 0) {
                return false;
            }
            // 将整数转为字符串
            String numStr = String.valueOf(x);
            int left = 0; // 左指针
            int right = numStr.length() - 1; // 右指针
            
            // 双指针向中间移动,比较字符
            while (left < right) {
                if (numStr.charAt(left) != numStr.charAt(right)) {
                    return false; // 字符不同,不是回文数
                }
                left++;
                right--;
            }
            return true; // 所有字符相同,是回文数
        }
    }

解法二:反转一半数字法(性能最高的解法)

 反转一半数字法是性能最优的解决方案。它通过数学运算只反转数字的后半部分,并与前半部分比较,避免了字符串转换和完全反转的溢出风险。

算法原理
  1. 处理特殊情况

    • 负数直接返回 false

    • 非零且末位为0的数(如10)直接返回 false

  2. 反转后半部分数字

    • 当剩余数字 > 反转数字时循环

    • 每次取原数字末位拼接到反转数字末尾

    • 原数字移除末位

  3. 比较两部分

    • 偶数位:反转部分 == 剩余数字

    • 奇数位:反转部分/10 == 剩余数字(忽略中间位)

性能分析
  • 时间复杂度:O(log₁₀n)

    • 循环次数 = 数字位数/2

    • 例如:12321 只需循环2次

  • 空间复杂度:O(1)

    • 仅使用常数级变量

class Solution {
    public boolean isPalindrome(int x) {
        /* 特殊情况处理:
           1. 负数不可能是回文数
           2. 非零数末位为0时不是回文数(因为数字开头不能是0) */
        if (x < 0 || (x % 10 == 0 && x != 0)) {
            return false;
        }

        int reversedHalf = 0; // 存储反转的后半部分数字
        
        // 当剩余数字 > 反转部分时继续循环
        while (x > reversedHalf) {
            // 将x的末位拼接到reversedHalf末尾
            reversedHalf = reversedHalf * 10 + x % 10;
            // 移除x的末位
            x /= 10;
        }
        
        /* 比较两部分:
           1. 偶数位数:x == reversedHalf
           2. 奇数位数:x == reversedHalf/10(忽略中间位) */
        return x == reversedHalf || x == reversedHalf / 10;
    }
}
优势说明
  1. 最优时间复杂度:仅需 O(log₁₀n) 时间

  2. 常数空间:无额外数据结构

  3. 避免溢出:只反转一半数字,确保不会溢出

  4. 数学运算高效:除法和取模操作是CPU基础指令

边界处理
  • 最大整数测试:2147483647 → 非回文数

  • 最小负数测试:-2147483648 → 直接返回false

  • 零处理:0 → 满足x==reversedHalf(0==0)

  • 末位零处理:10/20/100等 → 开头检测直接返回false

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值