LCP007 LeetCode 7 Reverse Integer

来源:互联网 发布:uwp软件 编辑:程序博客网 时间:2024/05/12 09:05

这里有N个坑。很考验基本功。

最初拿到这道题,然后就去边洗衣服边想了。刚开始还想x 的高位开始向下,然后把 ans 的从低位到高位排起(川话)。然而太麻烦了。
后来想出了x 从低位向高位一位一位地吃掉,然后把啃下来的低位数字*10加上下一个啃下来的低位数字。这样的不算很麻烦的思路。
于是又开始了递归的规划过程。因为之前在朋友家完成第226题时,简直惊艳于某网友的简洁递归代码。“于是再也没能忘掉你容颜”。终于敲出代码,并用123,-123试过之后成功得到excepted answer后,就submit。也算意料之中的,WA了。于是这就出现了一堆一堆的坑。于是就开始一次一次地修补自己的代码。希望能通过OJ,然并卵!

题目

Acceptance : 23.7% Difficulty : Easy
Reverse digits of an integer.
Example1: x = 123, return 321
Example2: x = -123, return -321

Have you thought about this?
Here are some good questions to ask before coding. Bonus points for you if you have already thought this!

If the integer’s last digit is 0, what should the output be? ie, case such as 10, 100.

Did you notice that the reversed integer might overflow ? Assume the input is a 32-bit integer, then reverse of 1000000003 overflows. How should you handle such cases ?

For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows.

TagsMath

题解

“闲言碎语不要讲”,我们直接来看Code。

class Solution {public:    int reverse(int x, long ans)    {        if (x == 0)            return ans;        else        {            ans = ans * 10 + x % 10;            x /= 10;            return reverse(x, ans);        }    }    int reverse(int x)     {        if (x < 0)        {            x = -x;            return -reverse(x, 0);        }        else            return reverse(x, 0);    }};

当我拿着上述code run custom testcase之后,兴高采烈地Submit。然而WA。当输入为“1534236469”时,excepted answer = 0, mine = 1056389759。于是点开了上面的spoilers。看到上述文章。
然则,如何判断我的结果会不会溢出呢?
于是,百度了判断int溢出的方法。有人提出了转换为unsigned int之后判断相加后的和是否大于定义在C的头文件< limits >中的INT_MAX
然而并没有切实掌握网友提供的方法。运行后结果仍然不对。
看到discussion中有个网友的非递归solution也是相当棒的,贴在下面:

int reverse(int x) {    int result = 0;    while (x != 0){        if (INT_MAX / 10 < result||INT_MIN/10>result){            result = 0;            break;        }        else{            result = result * 10 + x % 10;        }        x /= 10;    }    return result;}

不得不说这代码实在不比递归的啰嗦。(e。。。我是说,这代码真棒,比递归的还整洁)。思路清晰,除了大括号的位置可能因人而异之外。

然而看到里面的代码,我突发奇想。万一: INT_MAX / 10 是小于当前的result了,但是 当 result 加上 x 的最高位之后刚好大于 INT_MAX 怎么办?
#define INT_MAX 2147483647
那么刚好万一 x = 8463847412.或者9开头的数字。是不是就又突破了代码的防线,成功地bug出overflow了呢?
于是拿着他的代码运行了以846……为custom testcase的测试。
发现,答案是匹配的,但是excepted answer也是一个负值。

这应该不是正确的答案!!可能OJ出错了!!

我兴奋地以为自己发现了OJ的bug,却在刚刚那一刻,当我用font color = purple 打出上一句话的时候,忽然看到再往上几行的 x 的值好别扭啊。
!!!输入就已经溢出了!!!输入的数值并不是真的+846……,而将会是一个 -???? 值。

果然写blog还是有好处的。所以这时候,我们不得不再用calc.exe看一下这个case了。

8463847412 用十六进制看是0x1 F87C 0FF4。最高位溢出无效了,0xF87C 0FF4 所代表的十进制数是 -126087180。所以输出 -81780621 是正确的!!!

当然讨论输入是不是有效的32位int是另一回事情了。

有一个略简单的方法来判断溢出是先用long来声明ans,然后判断ans 是否大于MAX_INT 或者是否小于 MIN_INT 。然后再输出答案。

代码如下:

class Solution {public:    int reverse(int x, long ans)    {        if (x == 0)        {            if (ans > INT_MAX || ans < INT_MIN)            {                return 0;            }            return ans;        }        else        {            if (ans > INT_MAX || ans < INT_MIN)            {                return 0;            }            ans = ans * 10 + x % 10;            x /= 10;            return reverse(x, ans);        }    }    int reverse(int x)     {        if (x < 0)        {            x = -x;            return -reverse(x, 0);        }        else            return reverse(x, 0);    }};
0 0
原创粉丝点击