[LeetCode]9. 迴文數

題目

判斷一個整數是否是迴文數。迴文數是指正序(從左向右)和倒序(從右向左)讀都是一樣的整數。

示例 1:

輸入: 121
輸出: true

示例 2:

輸入: -121
輸出: false
解釋: 從左向右讀, 爲 -121 。 從右向左讀, 爲 121- 。因此它不是一個迴文數。

示例 3:

輸入: 10
輸出: false
解釋: 從右向左讀, 爲 01 。因此它不是一個迴文數。

進階:
你能不將整數轉爲字符串來解決這個問題嗎?

解題思路

解法一:轉字符數組

將數字先轉成字符串,再轉換成字符數組。設置 left、right 兩個雙指針,分別從前往後、從後往前遍歷。當遇到不一樣的字符時,直接返回 false;如果相同,繼續遍歷;當遍歷完字符數組之後,也沒發現不同的字符,則返回true。

複雜度分析:
時間複雜度:O(n)。我們需要遍歷整個字符數組。
空間複雜度:O(n)。我們需要O(n)的空間存放字符數組。

解法二:數學解法

將數字本身反轉,然後將反轉後的數字與原始數字進行比較,如果它們是相同的,那麼這個數字就是迴文。但是,如果反轉後的數字大於 INT.MAX,將遇到整數溢出問題。所以我們考慮只反轉 int 數字的一半,如果該數字是迴文,其後半部分反轉後應該與原始數字的前半部分相同。
例如,輸入 1221,我們可以將數字 “1221” 的後半部分從 “21” 反轉爲 “12”,並將其與前半部分 “12” 進行比較,因爲二者相同,所以數字 1221 是迴文。
在開始反轉之前先處理一些臨界情況:1)所有負數都不可能是迴文;2)除了 0 以外,所有個位是 0 的數字不可能是迴文,因爲最高位不等於 0,所以我們可以對所有大於 0 且個位是 0 的數字返回 false。
對於其他正常情況的反轉,例如數字 1221,如果執行 1221 % 10,我們將得到最後一位數字 1,要得到倒數第二位數字2,我們可以先通過除以 10 把最後一位數字 1 從 1221 中移除,1221 / 10 = 122,再將結果對 10 取餘,122 % 10 = 2,就可以得到倒數第二位數字。然後我們把最後一位數字乘以 10,再加上倒數第二位數字,1 * 10 + 2 = 12,就得到了我們想要的反轉後的數字。繼續這個過程,將得到更多位數的反轉數字。
由於整個過程我們不斷將原始數字除以 10,然後給反轉後的數字乘上 10,所以,當原始數字小於或等於反轉後的數字時,就意味着我們已經處理了一半位數的數字了。
由於迴文數的位數可奇可偶,所以當它的長度是偶數時,它對摺過來應該是相等的;當它的長度是奇數時,那麼它對摺過來後,有一個的長度需要去掉一位數(除以 10 並取整)。

具體步驟如下:
1)先判斷臨界情況。
2)每次進行取餘操作 ( %10),取出最低的數字:y = x % 10.
3)將最低的數字加到取出數的末尾:res = res * 10 + y.
4)每取一個最低位數字,x 都要自除以 10.
5)判斷 x 是不是小於 res ,當它小於的時候,說明數字已經對半或者過半了。
6)最後,判斷奇偶數情況:如果是偶數的話,res 和 x 相等;如果是奇數的話,最中間的數字就在res 的最低位上,將它除以 10 以後應該和 x 相等。

複雜度分析:
時間複雜度:O(logn)。對於每次迭代,我們會將輸入除以 10,因此時間複雜度爲 O(logn)。
空間複雜度:O(1)。我們只需要常數空間存放若干變量。

代碼

解法一:轉字符數組

class Solution {
    public boolean isPalindrome(int x) {
        String s = String.valueOf(x);
        char[] nums = s.toCharArray();
        int left = 0;
        int right = nums.length-1;
        while(left<=right){
            if(nums[left]==nums[right]){
                left++;
                right--;
            }else{
                return false;
            }
        }
        return true;
    }
}

解法二:數學解法

class Solution {
    public boolean isPalindrome(int x) {
        // 臨界情況
        if(x<0 || (x%10==0 && x!=0)){
            return false;
        }
        int res = 0;
        // 進行反轉
        while(x>res){
            res = res*10 + x%10;
            x /= 10;
        }
        // 處理奇偶情況
        return x == res || x == (res / 10);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章