算法學習之路7.整數反轉--堆棧、字符串逆序

題目描述

給出一個 32 位的有符號整數,你需要將這個整數中每位上的數字進行反轉。

示例 1:

輸入: 123
輸出: 321
 示例 2:

輸入: -123
輸出: -321
示例 3:

輸入: 120
輸出: 21
注意:

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

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/reverse-integer
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。


解答

這一題自己解來也想得簡單,直接轉成字符串,再逆序就好了。至於溢出感覺捕獲異常就可以了。還是可以很快得出答案的。

我的解法最後結果沒有進90%,我們還是看一個100%範例吧。

解法1:

public class Solution {
    public int Reverse(int x) {
        if (x < 0)
            {
                int.TryParse(new string((-x).ToString().Reverse().ToArray()), out x);
                return (-x);
            }
            else
            {
                int.TryParse(new string(x.ToString().Reverse().ToArray()), out x);
                return (x);
            }
    }
}

很簡潔是吧。哎。佩服。


解法2:

還是給出官方算法,雖然很笨,但還是很基礎的。

思路:

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

算法

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

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

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

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

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


但是,這種方法很危險,因爲當 temp = rev * 10 + pop; 時會導致溢出。

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

爲了便於解釋,我們假設rev 是正數。

1.如果temp=rev⋅10+pop 導致溢出,那麼一定有 rev≥ INTMAX/10 。
2.如果rev> INTMAX/10,那麼temp=rev⋅10+pop 一定會溢出。
3.如果rev== INTMAX/10,那麼只要pop>7,temp=rev⋅10+pop 就會溢出。當 rev 爲負時可以應用類似的邏輯。

class Solution {
public:
    int reverse(int x) {
        int rev = 0;
        while (x != 0) {
            int pop = x % 10;
            x /= 10;
            if (rev > INT_MAX/10 || (rev == INT_MAX / 10 && pop > 7)) return 0;
            if (rev < INT_MIN/10 || (rev == INT_MIN / 10 && pop < -8)) return 0;
            rev = rev * 10 + pop;
        }
        return rev;
    }
};


複雜度分析

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章