LeetCode - 解題筆記 - 8 - Palindrome Number

支錦銘發表於2020-12-13

Palindrome Number

Solution 1

既然題目中要求儘量不要把整數轉換成字串進行迴文判斷,那麼所有直接檢視各位數字的方法儘量都不要使用(思路都是一樣的)。從迴文數最根本的定義上來看:前一半和後一半的逆序是相同的,那麼可以通過把數字逆序進行判斷。在C++等語言中,直接逆序任意整數可能會溢位,因此需要只逆序後一半。由於我們儘量不要按照各個數位去檢查,因此比較靈活的地方就是要考慮如何判斷“過半”

根據上面的分析,我們不斷地對後面的數字逐位逆序,對於迴文數,會出現恰好逆序部分和未逆序部分相等(偶數個數位)和逆序部分去掉最高位和未逆序部分相等(奇數個數位)的情形。且過半前,逆序部分數字必然會小於未逆序部分(因為數位更少),因此只需要考慮逆序部分變得更大或相等的時候,是否滿足上述兩種情形即可。

邊界條件除了題目中規定的負數外,還有一個上述設計會出問題的情形,就是如果一個數字是十的整倍數(百、千……),那麼最後也會被判定為迴文數,因此要額外進行判定。

  • 時間複雜度: O ( n ) O(n) O(n) n n n為數字的位數
  • 空間複雜度: O ( 1 ) O(1) O(1),僅維護常數個狀態量
class Solution {
public:
    bool isPalindrome(int x) {
        // negative integers are not palindrome numbers
        if (x < 0) {
            return false;
        }
        
        // 特殊情形:如果非0的數尾部為若干個0,一定不是迴文數,但是下面的判斷流程可能會對整十倍數
        if (x % 10 == 0 && x != 0) {
            return false;
        }
        
        int xRev = 0; // 不能直接求逆位,會溢位
        // 始終後面那個會很小,總有一刻會相等(偶數個數位)或者變大(奇數個數位)
        while(x > xRev) {
            int temp = x % 10;
            xRev = xRev * 10 + temp;
            x = x / 10;
        }
        
        return (x == xRev) || (x == xRev / 10);
    }
};

Solution 2

python實現,由於python裡面沒有數的限制,因此可以不用管溢位地進行逆序了(當然如果按照上一個實現判斷一半的話,會少一半的時間)。

class Solution:
    def reverseInteger(self, x: int) -> int:
        ans = 0
        while x != 0:
            temp = x % 10
            ans = ans * 10 + temp
            x = x // 10
            
        return ans
    
    def isPalindrome(self, x: int) -> bool:
        if x < 0:
            return False
        
        xRev = self.reverseInteger(x)
        
        print(x, xRev)
        
        return x == xRev

相關文章