LeetCode | 7. Reverse Integer

题目链接:https://leetcode.com/problems/reverse-integer/
题目难度:Easy
题目描述:

Given a 32-bit signed integer, reverse digits of an integer.

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: 《LeetCode | 7. Reverse Integer》. For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows.

相关主题:Math

思路 1 (Runtime Error)

求各个数位的值,放入栈中,再恢复反转的数字,恢复时注意检查溢出。

时间复杂度:《LeetCode | 7. Reverse Integer》
空间复杂度:《LeetCode | 7. Reverse Integer》

// C++
// #include <stack>

class Solution {
public:
    int reverse(int x) {
        if (x == 0) {
            return 0;
        }
        bool pos = (x > 0);
        if (!pos) {
            x = x * (-1);
        }
        stack<int> stk;
        while (x / 10 > 0) {
            stk.push(x % 10);
            x = x / 10;
        }
        stk.push(x);

        int result = 0;
        while (stk.top() == 0) {
            stk.pop();
        }

        int times = 1;
        while (!stk.empty()) {
            int temp = stk.top();
            if (temp * times / times == temp) {
                temp = temp * times;
                if (result + temp - temp == result) {
                    result += temp;
                } else {
                    return 0;   // add overflow
                }
            } else {
                return 0;   // multiplication overflow
            }
            stk.pop();
            times *= 10;
        }

        if (result < 0) {
            return 0;   // add overflow
        } else if (!pos) {
            result = result * (-1);
        }

        return result;
    }
};

思路 2

参考官方的 Solution,发现上面的思路 1 有三个缺点。一是不能直接将正负数统一起来只考虑一种情况,它们的末位数字有差别;二是可以不用把每个数字都求出来后才开始恢复反转的数字,二者可以同时进行;三是这种“先计算、再求逆运算看是否为原值”的检查溢出的方式不好,提交到 LeetCode 后会因为溢出报 Runtime Error,而本地执行时不会。

针对第一点,我们可以分别考虑正数和负数的情况,它们只是在溢出处理上略有不同;针对第二点,我们可以让 times 乘到 result 上,而不是 temp 上;针对第三点,我们在执行可能溢出的操作前先根据 int 型的最大值(或最小值)算出上界(或下界),如果待执行的操作数超出了上界(或下界),则计算会溢出,就不执行计算。

在 C++ 中,INT_MAXINT_MIN 分别代表 int 型整数的最大值(《LeetCode | 7. Reverse Integer》)和最小值(《LeetCode | 7. Reverse Integer》)。另外,我们也可以 #include <limits>,然后用 numeric_limits<int>::max()numeric_limits<int>::min() 分别得到 int 型整数的最大值和最小值。

时间复杂度:《LeetCode | 7. Reverse Integer》
空间复杂度:《LeetCode | 7. Reverse Integer》

// C++
// #inlucde <limits>

class Solution {
public:
    int reverse(int x) {
        int imax = numeric_limits<int>::max();
        int imin = numeric_limits<int>::min();
        int result = 0;
        while (x != 0) {
            int pop = x % 10;
            x = x / 10;
            if (result > imax / 10 || (result == imax / 10 && pop > 7)) {
                return 0;
            }
            if (result < imin / 10 || (result == imin / 10 && pop < -8)) {
                return 0;
            }
            result = result * 10 + pop;
        }
        return result;
    }
};

2019年04月09日

    原文作者:听这一刻的晚风
    原文地址: https://www.jianshu.com/p/1473f0488438
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞