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。

猜你喜欢

转载自blog.csdn.net/qq_38003892/article/details/84781225
今日推荐