Question
Given an integer x, return true if x is a palindrome, and false otherwise.
Example 1:
Input: x = 121
Output: true
Explanation: 121 reads as 121 from left to right and from right to left.
Example 2:
Input: x = -121
Output: false
Explanation: From left to right, it reads -121. From right to left, it becomes 121-. Therefore it is not a palindrome.
Example 3:
Input: x = 10
Output: false
Explanation: Reads 01 from right to left. Therefore it is not a palindrome.
Constraints:
231 <= x <= 231 - 1
Follow up:
Could you solve it without converting the integer to a string?
Solution
Soluton A
- Conver Int to String
- Compare last character and first character, and then last char move backward, first char move forward.
Swift
class Solution {
func isPalindrome(_ x: Int) -> Bool {
if x < 0 {
return false
}
let digits = Array(String(x))
var left = 0
var right = digits.count - 1
while left < right {
if digits[left] != digits[right] {
return false
}
left += 1
right -= 1
}
return true
}
}
Swift - Using String or not Array
class Solution {
func isPalindrome(_ x: Int) -> Bool {
guard x >= 0 else { return false }
let str = String(x)
var left = str.startIndex
var right = str.index(before: str.endIndex)
while left < right {
if str[left] != str[right] {
return false
}
left = str.index(after: left)
right = str.index(before: right)
}
return true
}
}
JS - Double pointer
/**
* @param {number} x
* @return {boolean}
*/
var isPalindrome = function(x) {
if (x < 0) return false;
const str = String(x);
let i = 0
let j = str.length - 1
while (i < j) {
if (str[i] !== str[j]) return false;
i++
j--
}
return true;
};
JS - Array API reverse()
var isPalindrome = function(x) {
if (x < 0) return false;
const str = String(x);
const reversed = str.split('').reverse().join('');
return str === reversed;
};
Solution B
Using Math to get palindrome number, and compare original number and new generated number.
Swift
class Solution {
func isPalindrome(_ x: Int) -> Bool {
// 剪枝(Pruning): 负数一定不是回文;末尾为 0 的数字也不是(除非是 0 本身)
guard x >= 0, x % 10 != 0 || x == 0 else {
return false
}
var original = x
var reversed = 0
while original > 0 {
reversed = reversed * 10 + original % 10
original /= 10
}
return reversed == x
}
}
Solution B - Further optimize
Reverse only half of the digits
JS
/**
* @param {number} x
* @return {boolean}
*/
var isPalindrome = function(x) {
// Negative numbers and numbers ending with 0 (but not 0 itself) are not palindromes
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);
}
// For even-length numbers: x === reversedHalf
// For odd-length numbers: x === Math.floor(reversedHalf / 10)
return x === reversedHalf || x === Math.floor(reversedHalf / 10);
};
Swift
class Solution {
func isPalindrome(_ x: Int) -> Bool {
guard x >= 0, x % 10 != 0 || x == 0 else {
return false
}
var original = x
var reversedHalf = 0
// Reverse only half of the digits
while original > reversedHalf {
reversedHalf = reversedHalf * 10 + original % 10
original /= 10
}
// For even digits: original == reversedHalf
// For odd digits: original == reversedHalf / 10 (middle digit doesn't matter)
return original == reversedHalf || original == reversedHalf / 10
}
}
Inspiration
- Using
Math.floor(x / y)instead of justx / yin JavaScript - toFixed(2) is useful to keep 2 decimal places
| 方法 | 空间复杂度 | 可读性 | 面试推荐 |
|---|---|---|---|
| 字符串反转 | O(n) | ✅ 非常高 | ✅ 快速验证逻辑 |
| 双指针 | O(1) | ✅ 清晰 | ✅ 更高效(尤其对大数) |