Easy
题目描述
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。
回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
示例 1:
输入:x = 121
输出:true
解释:121 从左向右读为 121 ,从右向左读也为 121 。
示例 2:
输入:x = -121
输出:false
解释:从左向右读为 -121 。从右向左读为 121- 。因此它不是一个回文数。
示例 3:
输入:x = 10
输出:false
解释:从右向左读为 01 。因此它不是一个回文数。
提示:
- -2³¹ <= x <= 2³¹ - 1
进阶: 你能不将整数转为字符串来解决这个问题吗?
解题思路
解题思路
这道题有两种主要思路:
方法一:转换为字符串(简单直接)
将数字转换为字符串,然后比较字符串与其反转后的结果是否相等。这是最直观的方法。
方法二:数学方法(推荐)
不使用字符串转换,而是通过数学运算来判断:
特殊情况处理:
- 负数不可能是回文数,直接返回 false
- 以 0 结尾的正数(除了 0 本身)不可能是回文数,因为回文数不能以 0 开头
反转一半数字:
- 完全反转整个数字可能导致溢出
- 我们只需要反转数字的后半部分
- 当原数字小于等于反转数字时,说明已经处理了一半
判断条件:
- 对于偶数位数:
x == reversed - 对于奇数位数:
x == reversed / 10(去掉中间的数字)
- 对于偶数位数:
这种方法的优势是空间复杂度为 O(1),且避免了整数溢出的风险。
代码实现
class Solution {
public:
bool isPalindrome(int x) {
// 负数和以0结尾的正数(除了0)不是回文数
if (x < 0 || (x % 10 == 0 && x != 0)) {
return false;
}
int reversed = 0;
while (x > reversed) {
reversed = reversed * 10 + x % 10;
x /= 10;
}
// 偶数位数:x == reversed
// 奇数位数:x == reversed / 10
return x == reversed || x == reversed / 10;
}
};
class Solution:
def isPalindrome(self, x: int) -> bool:
# 负数和以0结尾的正数(除了0)不是回文数
if x < 0 or (x % 10 == 0 and x != 0):
return False
reversed_num = 0
while x > reversed_num:
reversed_num = reversed_num * 10 + x % 10
x //= 10
# 偶数位数:x == reversed_num
# 奇数位数:x == reversed_num // 10
return x == reversed_num or x == reversed_num // 10
public class Solution {
public bool IsPalindrome(int x) {
// 负数和以0结尾的正数(除了0)不是回文数
if (x < 0 || (x % 10 == 0 && x != 0)) {
return false;
}
int reversed = 0;
while (x > reversed) {
reversed = reversed * 10 + x % 10;
x /= 10;
}
// 偶数位数:x == reversed
// 奇数位数:x == reversed / 10
return x == reversed || x == reversed / 10;
}
}
var isPalindrome = function(x) {
if (x < 0) return false;
let original = x;
let reversed = 0;
while (x > 0) {
reversed = reversed * 10 + x % 10;
x = Math.floor(x / 10);
}
return original === reversed;
};
复杂度分析
| 复杂度 | 数学方法 | 字符串方法 |
|---|---|---|
| 时间复杂度 | O(log n) | O(log n) |
| 空间复杂度 | O(1) | O(log n) |
其中 n 是输入数字的值,log n 表示数字的位数。数学方法具有更优的空间复杂度。