LeetCode | 7. Reverse Integer

来源:互联网 发布:c语言输出buffer内容 编辑:程序博客网 时间:2024/06/06 06:52

题目

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 through this!

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

Did you notice that the reversed integer might overflow? Assume the input is a 32-bit integer, then the 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.

Note:

The input is assumed to be a 32-bit signed integer. Your function should return 0 when the reversed integer overflows.

我的思路

根据题目的提示,主要注意判断如下几种情况:

  1. 数字后面的数为 0 时,需要如何转换;
  2. 数字反转后有可能会溢出(例如,1000000003)。32 位 int 取值范围为(2 ^ 32 / 2 = 2147483648):[-2147483648, 2147483647],反转时注意与这两个数进行比较即可。
  3. 如果数字是一位数,那么直接返回该数字即可。

区分好上述情况之后,剩下的问题就比较简单了。利用出发和求余即可提取出数字的每一位数,然后把这些数字组合成答案。

代码

int reverse(int x) {    // 32-bit signed integer: [-2147483648, 2147483647]    // 2 ^ 32 / 2 = 2147483648    const int max = 2147483647;    const int min = -2147483648;    int i = 0, j = 0;    int tmp1 = 0, tmp2 = 0, divisor = 0;    int len = 0, maxLen = 0;    int res = 0;    if((x > -10) && (x < 10)) {        return x;    }    tmp1 = x;    do {        len++;        tmp1 = tmp1 / 10;    } while(tmp1 != 0);    tmp1 = max;    do {        maxLen++;        tmp1 = tmp1 / 10;    } while(tmp1 != 0);    if(len > maxLen) {        // Overflow        return 0;    }    else if(len == maxLen) {        if(x >= 0) {            tmp1 = x;            tmp2 = max;        }        else {            tmp1 = x;            tmp2 = min;        }        for(i = maxLen - 1; i >= 0; i--) {            divisor = 1;            for(j = 0; j < i; j++) {                divisor *= 10;            }            //printf("tmp1 = %d, tmp2 = %d\n", tmp1, tmp2);            if(abs(tmp1 % 10) > abs(tmp2 / divisor)) {                // Overflow                return 0;            }            else if(abs(tmp1 % 10) < abs(tmp2 / divisor)) {                break;            }            tmp1 = tmp1 / 10;            tmp2 = tmp2 % divisor;        }    }    tmp1 = x;    tmp2 = 1;    for(i = 0; i < len - 1; i++) {        tmp2 *= 10;    }    for(i = len - 1; i >= 0; i--) {        divisor = 1;        for(j = 0; j < i; j++) {            divisor *= 10;        }        res = res + (tmp1 / divisor) * (tmp2 / divisor);        tmp1 = tmp1 % divisor;    }    return res;}

优化代码

下面的优化代码来源于 leetcode.com 其他人的 submission。

上述代码在提交到 leetcode.com 后运行时间太长了,效率很低。于是参考了下效率比较高的代码。

  1. 优化后的代码通过一个数组 num[20] 来保存输入整数 x 中每一位数字,然后通过操作数组 num[20] 得到最后的结果。

  2. 优化后的代码对输入的整数 x 进行处理(if(x < 0)return (-1) * reverse((-1) * x);),使得后半部分的代码不用区分正负数,从而简化了代码。

  3. 优化后的代码使用了 long long 类型的变量 temp 来保存反转后的数据,这样就可以保证了反转后的数据即使超出 int 的取值范围,也不会出现 Runtime Error。

#include <limits.h>int reverse(int x) {    if(x > INT_MAX || x < INT_MIN + 1)        return 0;    if(x == 0)        return 0;    if(x < 0)        return (-1) * reverse((-1) * x);    int num[20] = {0};    int top = 0, end = 0;    long long temp = 0;    for(temp = x; temp > 0; top++) {        num[top] = temp % 10;        temp = temp / 10;    }    top--;    for(temp = 0, end = 0; end <= top; end++) {        temp = temp * 10 + num[end];        if(temp >= INT_MAX)            return 0;    }    return temp;}
原创粉丝点击