leetCode 9 Palindrome Number

leetcode.windliang.cc/ 第一時間發佈html

題目描述(簡單難度)

判斷是否是迴文數,負數不是迴文數。java

解法一

把 int 轉成字符串,而後判斷是不是迴文串作就能夠了,缺點是須要額外的空間存儲字符串,固然題目也告訴了不能這樣,因此 pass 。git

解法二

第 7 道題咱們寫了倒置 int 的算法,這裏固然能夠用到了,只須要判斷倒置先後相不相等就能夠了。算法

記不記得,當倒置後的數字超出 int 的範圍時,咱們返回的是 0 ,那麼它必定不等於原數,此時必定返回 false 了,這正不正確呢?spa

咱們只需證實,若是倒置後超出 int 的範圍,那麼它必定不是迴文數字就行了。code

反證法,咱們假設存在這麼一個數,倒置後是超出 int 範圍的,而且它是迴文數字。cdn

int 最大爲 2147483647 ,htm

讓咱們來討論這個數多是多少。blog

有沒有多是最高位大於 2 致使的溢出,好比最高位是 3 ,由於是迴文串,因此最低位是 3 ,這就將致使轉置前最高位也會是 3 ,因此不多是這種狀況。leetcode

有沒有多是第 2 高位大於 1 致使的溢出,此時保持最高位不變,假如第 2 高位是 2,由於是迴文串,因此個位是 2,十位是 2 ,一樣的會致使倒置前超出了 int 的最大值,因此也不多是這種狀況。

同理,第 3 高位,第 4,第 5,直線左邊的都是上述的狀況,因此不多是前邊的位數過大。

爲了保證這個數是溢出的,前邊 5 位必須固定不變了,由於它是迴文串,因此直線後的灰色數字就必定是 4 ,而此時無論後邊的數字取多少,都不多是溢出的了。

綜上,不存在這樣一個數,因此能夠安心的寫代碼了。

public int reverse(int x) {
    int rev = 0;
    while (x != 0) {
        int pop = x % 10;
        x /= 10;
        if (rev > Integer.MAX_VALUE / 10)
            return 0;
        if (rev < Integer.MIN_VALUE / 10)
            return 0;
        rev = rev * 10 + pop;
    }
    return rev;
}

public boolean isPalindrome(int x) {
    if (x < 0) {
        return false;
    }
    int rev = reverse(x);
    return x == rev;
}
複製代碼

時間複雜度:和求轉置同樣,x 有多少位,就循環多少次,因此是 O(log(x)) 。

空間複雜度:O(1)。

解法三

其實,咱們只須要將右半部分倒置而後和左半部比較就能夠了。好比 1221 ,把 21 轉置和 12 比較就好了。

public boolean isPalindrome(int x) {
    if (x < 0) {
        return false;
    }
    int digit = (int) (Math.log(x) / Math.log(10) + 1); //總位數
    int revert = 0;
    int pop = 0;
    //倒置右半部分 
    for (int i = 0; i < digit / 2; i++) { 
        pop = x % 10;
        revert = revert * 10 + pop;
        x /= 10;
    }
    if (digit % 2 == 0 && x == revert) {
        return true;
    }
    //奇數狀況 x 除以 10 去除 1 位
    if (digit % 2 != 0 && x / 10 == revert) { 
        return true;
    }
    return false;
}
複製代碼

時間複雜度:循環 x 的總位數的一半次,因此時間複雜度依舊是 O(log(x))。

空間複雜度:O(1),常數個變量。

總結

這幾天都比較簡單,加油加油加油!。

相關文章
相關標籤/搜索