1. 程式人生 > >LeetCode題目詳解-7反轉整數

LeetCode題目詳解-7反轉整數

7.反轉整數

題目:

給定一個 32 位有符號整數,將整數中的數字進行反轉。

示例 1:

輸入: 123
輸出: 321

 示例 2:

輸入: -123
輸出: -321

示例 3:

輸入: 120
輸出: 21

注意:

假設我們的環境只能儲存 32 位有符號整數,其數值範圍是 [−231,  231 − 1]。根據這個假設,如果反轉後的整數溢位,則返回 0。

程式碼:

class Solution {
public:
    int reverse(int x) {
        int a, rev=0;
        while(x){
            a = x%10;
            x = x/10;
            if(rev>INT_MAX/10 || (rev==INT_MAX/10 && a>7)){
                return 0;
            }
            if(rev<INT_MIN/10 || (rev==INT_MIN/10 && a<(-8))){
                return 0;
            }
            rev = rev*10 + a;
        }
//或者如下操作:
//        while(x){
//            a = x%10;
//            x = x/10;
//            int tmp = rev*10 + a;
//            if(tmp/10 != rev){//若新改變後的tmp已經溢位,則tmp/10不會等於之前的rev
//                return 0;
//            }
//            rev = tmp;
//        }
        return rev;
    }
};

方法:彈出和推入數字 & 溢位前進行檢查

思路

我們可以一次構建反轉整數的一位數字。在這樣做的時候,我們可以預先檢查向原整數附加另一位數字是否會導致溢位。

演算法

反轉整數的方法可以與反轉字串進行類比。

我們想重複“彈出” xx 的最後一位數字,並將它“推入”到 rev 的後面。最後,rev 將與 xx 相反。

要在沒有輔助堆疊 / 陣列的幫助下 “彈出” 和 “推入” 數字,我們可以使用數學方法。

//pop operation:
pop = x % 10;
x /= 10;

//push operation:
temp = rev * 10 + pop;
rev = temp;

但是,這種方法很危險,因為當 temp=rev⋅10+pop 時會導致溢位。

幸運的是,事先檢查這個語句是否會導致溢位很容易。

為了便於解釋,我們假設 \text{rev}rev 是正數。

  1. 如果 temp=rev⋅10+pop 導致溢位,那麼一定有 rev≥INT_MAX​ / 10。
  2. 如果 rev>INT_MAX / 10​,那麼 temp=rev⋅10+pop 一定會溢位。
  3. 如果 rev==INT_MAX / 10​,那麼只要 pop>7,temp=rev⋅10+pop 就會溢位。

當 rev 為負時可以應用類似的邏輯。

複雜度分析

  • 時間複雜度:O(log(x)),xx 中大約有log10​(x) 位數字。
  • 空間複雜度:O(1)。