欢迎来到李耶的频道【LeetCode面试题】。
回文数
题目
给你一个整数 x,如果 x 是一个回文整数,返回 true;否则,返回 false。
回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
- 例如,
121是回文,而123不是。
进阶: 你能不将整数转为字符串来解决这个问题吗?
输入:x = 121
输出:true
输入:x = -121
输出:false
解释:从左向右读为 -121,从右向左读为 121-,因此它不是一个回文数。
输入:x = 10
输出:false
解释:从右向左读为 01,因此它不是一个回文数。
解法一:反转一半数字
思路:将数字的后半部分反转,与前一半比较。当原始数字小于或等于反转数字时,说明已经处理了一半的数字。这样避免了反转整个数字可能导致的溢出问题。
javascript
function isPalindrome(x) {
// 负数或以 0 结尾的正数(0 除外)不可能是回文
if (x < 0 || (x % 10 === 0 && x !== 0)) {
return false;
}
let reversedHalf = 0;
while (x > reversedHalf) {
reversedHalf = reversedHalf * 10 + x % 10;
x = Math.floor(x / 10);
}
// 偶数位回文:x === reversedHalf
// 奇数位回文:x === Math.floor(reversedHalf / 10),如 12321,处理后 x=12, reversedHalf=123
return x === reversedHalf || x === Math.floor(reversedHalf / 10);
}
- 时间复杂度 / 空间复杂度:O(log₁₀ x) / O(1)
- 优势:不转字符串,不溢出,空间最优,是面试中最推荐的写法
解法二:转字符串法
思路:将整数转为字符串,然后使用双指针从头尾向中间比较。代码直观易懂,但未满足进阶要求。
javascript
function isPalindrome(x) {
if (x < 0) return false;
const str = x.toString();
let left = 0;
let right = str.length - 1;
while (left < right) {
if (str[left] !== str[right]) {
return false;
}
left++;
right--;
}
return true;
}
- 时间复杂度 / 空间复杂度:O(log₁₀ x) / O(log₁₀ x)
- 优势:代码简洁直观,容易理解
- 劣势:不符合进阶要求(不转字符串),面试中可作为过渡解法
解法对比
| 解法 | 时间 / 空间复杂度 | 不转字符串 | 推荐指数 |
|---|---|---|---|
| 反转一半数字 | O(log₁₀ x) / O(1) | ✅ | ⭐⭐⭐⭐⭐ |
| 转字符串法 | O(log₁₀ x) / O(log₁₀ x) | ❌ | ⭐⭐⭐ |
扩展题
- 回文链表:判断一个单链表是否为回文链表,要求时间复杂度 O(n)、空间复杂度 O(1)。
- 回文子串:给定一个字符串,统计其中回文子串的数量。
- 最长回文子串:给定一个字符串,找到其中最长的回文子串。
"行有不得,反求诸己。" ------ 《孟子·离娄上》
关注李耶,每天一道面试题,一起卷起来 🔥