【LeetCode】9. 回文数
方法分析
-
特殊情况处理:
- 负数直接返回
false(如示例2中的-121); - 非零但末位为0的数(如示例3中的
10)也直接返回false,因为回文数不可能以0开头(除非是0本身)。
- 负数直接返回
-
反转一半数字:
通过数学运算反转整数的后半部分,避免字符串转换或完整反转可能导致的溢出问题。例如,对于x = 1221,反转后半部分的21得到12,与原数的前半部分12相等,说明是回文数。 -
奇偶位数处理:
- 偶数位:反转后的后半部分与原前半部分直接比较(如
1221→12vs12); - 奇数位:反转后的后半部分需去掉中间位再比较(如
12321→123去掉中间位3,得到12vs12)。
- 偶数位:反转后的后半部分与原前半部分直接比较(如
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))),但需额外空间且效率较低。 - 数学法(推荐):直接操作数字,高效且无溢出风险,符合题目要求。

浙公网安备 33010602011771号