9. Palindrome Number

69 阅读2分钟

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

  1. Conver Int to String
  2. 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

  1. Using Math.floor(x / y) instead of just x / y in JavaScript
  2. toFixed(2) is useful to keep 2 decimal places
方法空间复杂度可读性面试推荐
字符串反转O(n)✅ 非常高✅ 快速验证逻辑
双指针O(1)✅ 清晰✅ 更高效(尤其对大数)