1. 程式人生 > >[LeetCode] Reverse Integer 翻轉整數

[LeetCode] Reverse Integer 翻轉整數

Reverse digits of an integer.

Example1: x = 123, return 321
Example2: x = -123, return -321

Have you thought about this?

Here are some good questions to ask before coding. Bonus points for you if you have already thought through this!

If the integer's last digit is 0, what should the output be? ie, cases such as 10, 100.

Did you notice that the reversed integer might overflow? Assume the input is a 32-bit integer, then the reverse of 1000000003 overflows. How should you handle such cases?

For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows.

Update (2014-11-10):
Test cases had been added to test the overflow behavior.

翻轉數字問題需要注意的就是溢位問題,看了許多網上的解法,由於之前的OJ沒有對溢位進行測試,所以網上很多人的解法沒有處理溢位問題也能通過OJ。現在OJ更新了溢位測試,所以還是要考慮到。為什麼會存在溢位問題呢,我們知道int型的數值範圍是 -2147483648~2147483647, 那麼如果我們要翻轉 1000000009 這個在範圍內的數得到 9000000001,而翻轉後的數就超過了範圍。 我最開始的想法是,用long long 型資料,其數值範圍為 -9223372036854775808~9223372036854775807, 遠大於int型這樣就不會出現溢位問題。程式碼如下: 解法一:
/*
* * Correct but can refactor the code. */ class Solution { public: int reverse(int x) { long long res = 0; bool isPositive = true; if (x < 0) { isPositive = false; x *= -1; } while (x > 0) { res = res * 10 + x % 10; x /= 10; } if (res > INT_MAX) return 0; if (isPositive) return res; else return -res; } };

提交通過後,OJ給出了官方解答,一看比自己的寫的更精簡一些,它沒有特意處理正負號,仔細一想,果然正負號不影響計算,而且沒有用long long型資料,感覺寫的更好一些,那麼就貼出來吧:

解法二:

class Solution {
public:
    int reverse(int x) {
        int res = 0;
        while (x != 0) {
            if (abs(res) > INT_MAX / 10) return 0;
            res = res * 10 + x % 10;
            x /= 10;
        }
        return res;
    }
};

在貼出答案的同時,OJ還提了一個問題 To check for overflow/underflow, we could check if ret > 214748364 or ret < –214748364 before multiplying by 10. On the other hand, we do not need to check if ret == 214748364, why? (214748364 即為 INT_MAX / 10

為什麼不用check是否等於214748364呢,因為輸入的x也是一個整型數,所以x的範圍也應該在 -2147483648~2147483647 之間,那麼x的第一位只能是1或者2,翻轉之後res的最後一位只能是1或2,所以res只能是 2147483641 或 2147483642 都在int的範圍內。但是它們對應的x為 1463847412 和 2463847412,後者超出了數值範圍。所以當過程中res等於 214748364 時, 輸入的x只能為 1463847412, 翻轉後的結果為 2147483641,都在正確的範圍內,所以不用check。

我們也可以用long long型變數儲存計算結果,最後返回的時候判斷是否在int返回內,參見程式碼如下:

解法三:

class Solution {
public:
    int reverse(int x) {
        long long res = 0;
        while (x != 0) {
            res = 10 * res + x % 10;
            x /= 10;
        }
        return (res > INT_MAX || res < INT_MIN) ? 0 : res;
    }
};

下面這種方法是上面解法二的變形,其實也不難理解,因為都是用int型的,如果超出了範圍,其除以10的結果就不會跟之前的結果一致,通過這點也可以進行區分,參見程式碼如下:

解法四:

class Solution {
public:
    int reverse(int x) {
        int res = 0;
        while (x != 0) {
            int t = res * 10 + x % 10;
            if (t / 10 != res) return 0;
            res = t;
            x /= 10;
        }
        return res;
    }
};

參考資料: