Leetcode-Reverse Integer(java)

1 Description(描述)

Given a 32-bit signed integer, reverse digits of an integer.
給定一個32位的有符號整數,倒置整數中的每一位數。

Example 1:
Input: 123
Output: 321

Example 2:
Input: -123
Output: -321

Example 3:
Input: 120
Output: 21

Note:(注意)
Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−231, 231 − 1]. For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows.
假設我們處理的環境只能存儲32位的有符號數,其範圍是[−231, 231 − 1]。對於這個問題,可以假設當倒置後的整數溢出時,你的方法返回0。

2 Solution(解決方案)

Approach 1: Pop and Push Digits & Check before Overflow
方法1:Pop和Push數字 & 溢出前檢查

Intuition(直覺)
We can build up the reverse integer one digit at a time. While doing so, we can check beforehand whether or not appending another digit would cause overflow.
我們可以每次只建立倒置整數中的一個數。我這麼做,我們可以在添加另一個數時檢查是否溢出。

Algorithm(算法)
Reversing an integer can be done similarly to reversing a string
倒置一個整數跟倒置一個字符串相似。

We want to repeatedly “pop” the last digit off of x and “push” it to the back of the rev. In the end, rev will be the reverse of the x.
我們想要反覆地 “pop” x 的最後一位數,並且 “push” 這個數到 rev 的末尾,最後 rev 就是 x 的倒置。

To “pop” and “push” digits without the help of some auxiliary stack/array, we can use math.
在沒有一些輔助的棧和數組的幫助下,我們可以使用數學方法 “pop” 和 “push” 數字。

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

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

However, this approach is dangerous, because the statement rev = rev * 10 + pop can cause overflow.
然而,這個方法不安全,因爲 rev = rev * 10 + pop 的狀態可能造成溢出。

Luckily, it is easy to check beforehand whether or this statement would cause an overflow.
幸運的是,事先檢查這個語句是否會導致溢出是很容易的。

To explain, lets assume that rev is positive.
(1)If rev = rev * 10 + pop causes overflow, then it must be that rev ≥ INTMAX / 10.
(2)If rev > INTMAX / 10, then rev = rev * 10 + pop is guaranteed to overflow.
(3)If rev == INTMAX / 10 , then rev = rev * 10 + pop will overflow if and only if pop > 7.
Similar logic can be applied when rev is negative.

爲了更好地解釋,我們假設rev是正數。
如果rev = rev * 10 + pop造成溢出,此時一定有rev ≥ INTMAX / 10。
如果rev > INTMAX / 10,rev = rev * 10 + pop 一定會溢出。
如果rev == INTMAX / 10,rev = rev * 10 + pop當且僅當pop > 7時溢出。
當rev是負數時,也是相同的邏輯。

注:這裏第3點第一看到有點不太理解,在這裏利用java代碼解釋一下。
在這裏插入圖片描述
在這裏插入圖片描述
因此很好理解當pop大於7,rev等於INTMAX / 10時,rev = rev * 10 + pop一定會溢出。

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

Complexity Analysis(複雜度分析)
1 Time Complexity: O(log(x)). There are roughly log10(x) digits in x.
1 時間複雜度:O(log(x))。在x中大約有log10(x)個數。
2 Space Complexity: O(1).
2 空間複雜度:O(1)。

方法2:利用字符串(這也是我第一眼看到問題的想法,下面給出網友寫的非常不錯的代碼)

class Solution {
    public int reverse(int x) {
        boolean isPositive = x >= 0;
        char[] chars = (x + "").substring(isPositive ? 0 : 1).toCharArray();
        StringBuilder sb = new StringBuilder();
        for(char c : chars){
            sb.append(c);
        }
        long res = isPositive ? Long.valueOf(sb.reverse().toString()) : - Long.valueOf(sb.reverse().toString());
        return  res > Integer.MAX_VALUE || res < Integer.MIN_VALUE ? 0 : (int) res;
    }
}

注:內容均來源於leetcode。

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