【LeetCode】9. 回文数

leetcode

方法分析

  1. 特殊情况处理

    • 负数直接返回 false(如示例2中的 -121);
    • 非零但末位为0的数(如示例3中的 10)也直接返回 false,因为回文数不可能以0开头(除非是0本身)。
  2. 反转一半数字
    通过数学运算反转整数的后半部分,避免字符串转换或完整反转可能导致的溢出问题。例如,对于 x = 1221,反转后半部分的 21 得到 12,与原数的前半部分 12 相等,说明是回文数。

  3. 奇偶位数处理

    • 偶数位:反转后的后半部分与原前半部分直接比较(如 1221 → 12 vs 12);
    • 奇数位:反转后的后半部分需去掉中间位再比较(如 12321 → 123 去掉中间位 3,得到 12 vs 12)。

Golang实现代码

func isPalindrome(x int) bool {
    // 处理特殊情况:负数或末位为0的非零数
    if x < 0 || (x % 10 == 0 && x != 0) {
        return false
    }
    
    reversed := 0
    // 反转后半部分,直到原数小于等于反转后的数
    for x > reversed {
        reversed = reversed * 10 + x % 10
        x /= 10
    }
    
    // 偶数位直接比较,奇数位需去掉中间位
    return x == reversed || x == reversed / 10
}

代码解析

  • 时间复杂度:O(log n),仅需遍历数字的一半位数。
  • 空间复杂度:O(1),未使用额外空间。
  • 关键逻辑
    • 循环中每次将原数 x 的最后一位加到 reversed,并移除原数的末位(x /= 10);
    • 当 x 小于等于 reversed 时停止循环,此时已反转一半或过半位数;
    • 最终比较原数前半部分与反转后的后半部分是否相等(考虑奇偶位数差异)。

示例测试

fmt.Println(isPalindrome(121))   // true
fmt.Println(isPalindrome(-121))  // false
fmt.Println(isPalindrome(10))    // false
fmt.Println(isPalindrome(12321)) // true

方法对比

  • 字符串法:将数字转为字符串后判断对称性(如 strconv.Itoa(x) == reverse(strconv.Itoa(x))),但需额外空间且效率较低。
  • 数学法​(推荐):直接操作数字,高效且无溢出风险,符合题目要求。

 

posted @ 2025-03-12 12:43  云隙之间  阅读(46)  评论(0)    收藏  举报