反向整数leetcode - 如何处理溢出

时间:2014-01-12 02:17:01

标签: java algorithm integer reverse

问题是: 反转整数的数字。

示例1:x = 123,返回321

示例2:x = -123,返回-321

您是否注意到反转的整数可能会溢出?假设输入是32位整数,则反向1000000003溢出。你应该如何处理这类案件?

抛出异常?很好,但如果抛出异常不是一种选择呢?然后,您必须重新设计该功能(即添加一个额外的参数)。

我搜索网站的解决方案是:

public class Solution {

     public static int reverse(int x) {
            int ret = 0;
            boolean zero = false;
            while (!zero) {
                ret = ret * 10 + (x % 10);
                x /= 10;      
                if(x == 0){
                    zero = true;
                }
            }
            return ret;   
        }

    public static void main(String[] args) {
        int s = 1000000003;
        System.out.println(reverse(s));
    }

}

但是当s = 1000000003时,控制台会打印-1294967295而不是3000000001。因此,如果我们不能使用异常,这个解决方案仍然无法解决溢出问题。这里有什么帮助?(虽然有一个提示:添加一个额外的参数,我仍然无法弄清楚我应该添加什么参数)

25 个答案:

答案 0 :(得分:14)

除了int之外,不需要任何数据类型。 只需确保当有一个操作增加一个数字时,反转操作应该给你以前的数字。否则,就会溢出。

public int reverse(int x) {
    int y = 0;

    while(x != 0) {
        int yy = y*10 + x%10;

        if ((yy - x%10)/10 != y) return 0;
        else y = yy;

        x = x/10;   
    }
    return y;
}

答案 1 :(得分:9)

上面的大多数答案都有一个小问题,那就是int变量可能会溢出。您可以尝试:x = -2147483648作为参数。 有一种简单的方法可以解决这个问题。将x转换为long,并检查结果是否> = Integer.MAX_VALUE,否则返回0。 该解决方案通过https://leetcode.com/problems/reverse-integer/上的所有测试用例     

    这是一个java版本。

public int reverse(int x) {
        long k = x;
        boolean isNegtive = false;        
        if(k < 0){
            k = 0 - k;
            isNegtive = true;
        }

        long result = 0;
        while(k != 0){
            result *= 10;
            result += k % 10;
            k /= 10;
        }

        if(result > Integer.MAX_VALUE) return 0;
        return isNegtive  ? 0 - ((int)result) : (int)result;
    }

C#版

    public int Reverse(int x)
    {
        long value = 0;
        bool negative = x < 0;
        long y = x;
        y = Math.Abs(y);

        while (y > 0)
        {
            value *= 10;
            value += y % 10;
            y /= 10;
        }

        if(value > int.MaxValue)
        {
            return int.MaxValue;
        }

        int ret = (int)value;

        if (negative)
        {
            return 0 - ret;
        }
        else
        {
            return ret;
        }
    }

Python版本

def reverse(self, x):                
    isNegative = x < 0
    ret = 0
    x = abs(x)
    while x > 0:
        ret *= 10
        ret += x % 10
        x /= 10
    if ret > 1<<31:
        return 0

    if isNegative:
        return 0 - ret
    else:
        return ret

答案 2 :(得分:3)

这个java代码处理溢出条件:

public int reverse(int x) {

    long reverse = 0;
    while( x != 0 ) {
       reverse = reverse * 10 + x % 10;
       x = x/10;
    }

    if(reverse > Integer.MAX_VALUE || reverse < Integer.MIN_VALUE) {
        return 0;
    } else {
        return (int) reverse;
    }
}

答案 3 :(得分:2)

你可以在java中使用字符串来试试这个代码

class Solution {
    public int reverse(int x) {
        int n = Math.abs(x);
        String num = Integer.toString(n);
        StringBuilder sb = new StringBuilder(num);
        sb.reverse();
        String sb1;
    
        sb1 = sb.toString();
        
        int foo;
        try {
            foo = Integer.parseInt(sb1);
        }
        catch (NumberFormatException e){
            foo = 0;
        }
        if(x < 0){
            foo *= -1;
        }
        
        return foo;
    }
}

答案 4 :(得分:2)

这是一个古老的问题,但是无论如何,我也要解决这个问题!我只是在leetcode上解决了它。通过此检查,您永远不会在任何一个方向上遇到上溢/下溢,并且我认为代码比列出的所有代码更简洁。它通过了所有测试用例。

public int reverse(int x) {
    int y = 0;
    while(x != 0) {
        if(y > Integer.MAX_VALUE/10 || y < Integer.MIN_VALUE/10) return 0;
        y *= 10;
        y += x % 10;
        x /= 10;
    }
    return y;
}

答案 5 :(得分:1)

class Solution {
public:
  int reverse(int x) {
    char str[11];
    bool isNegative = false;
    int i;
    int ret = 0;

    if ( x < 0 ) {
        isNegative = true;
        x = -x;
    }

    i = 0;
    while ( x != 0 ) {
        str[i++] = x % 10 + '0';
        x = x / 10;
    }
    str[i] = '\0';

    if ( (isNegative && strlen(str) == 10 && strcmp(str, "2147483648") > 0) || (!isNegative && strlen(str) == 10 && strcmp(str, "2147483647") > 0) ) {
        cout << "Out of range!" << endl;
        throw new exception();
    }

    i = 0;
    int strLen = (int)strlen(str);
    while ( str[i] != '\0' ) {
        ret += ((str[i] - '0') * pow(10.0, strLen - 1 - i));
        i++;
    }

    return (isNegative ? -ret : ret);
}

};

答案 6 :(得分:1)

昨晚,我尝试了同样的问题,并在python中找到了一个简单的解决方案,如下所示,在检查了正数或负数后,这里给出了答案,尽管我在不同的部分都对它们进行了尝试,但是已经将负数转换为正数,并且在返回反向数之前,我已经将数字转换为负数。

对于处理溢出,我只是简单地检查了32位带符号数字的上限和数字的下限,它接受了我的回答,谢谢。

<p *ngFor="let item of items | keyvalue">
  {{'KEY: '+item.key + ', VALUE: ' + item.value }}
</p>

答案 7 :(得分:1)

这有效:

$scope.scale = 'lin'.

我尝试提高性能,但我能想出的就是:

public class Solution {
    public int reverse(int x) {
        long tmp = Math.abs((long)x);
        long res = 0;

        while(tmp >= 10){
            res += tmp%10;
            res*=10;
            tmp=tmp/10;          
        }  

        res+=tmp;

        if(x<0){
            res = -res;
        }

        return (res>Integer.MAX_VALUE||res<Integer.MIN_VALUE)? 0: (int)res; 
    }
}

它的C#等价物比我机器上的第一个版本运行速度快5%,但他们的服务器说它速度较慢,这不可能 - 我在这里摆脱了额外的函数调用,否则基本上是相同的。根据语言(C#或Java),它使我在60-30%之间。也许他们的基准测试代码不是很好 - 如果你多次提交 - 结果时间变化很大。

答案 8 :(得分:0)

我的解决方案没有使用很长时间:

public class ReverseInteger {

    public static void main(String[] args) {
        int input = Integer.MAX_VALUE;
        int output = reverse(input);
        System.out.println(output);
    }

    public static int reverse(int x) {
        int remainder = 0;
        int result = 0;

        if (x < 10 && x > -10) {
            return x;
        }

        while (x != 0) {
            remainder = x % 10;

            int absResult = Math.abs(result);
            int maxResultMultipliedBy10 = Integer.MAX_VALUE / 10;
            if (absResult > maxResultMultipliedBy10) {
                return 0;
            }

            int resultMultipliedBy10 = absResult * 10;

            int maxRemainder = Integer.MAX_VALUE - resultMultipliedBy10;
            if (remainder > maxRemainder) {
                return 0;
            }

            result = result * 10 + remainder;
            x = x / 10;
        }

        return result;
    }

}

答案 9 :(得分:0)

发布了几个很好的解决方案。这是我的 JS 解决方案:

const reverse = function (x) {
  const strReversed = x.toString().split("").reverse().join("");
  rv =
    parseInt(strReversed) > Math.pow(2, 31)
      ? 0
      : Math.sign(x) * parseInt(strReversed);

  return rv;
};

答案 10 :(得分:0)

以下是用JS(Javascript编码)的解决方案,它已通过Leetcode成功解决了所有问题( https://leetcode.com/problems/reverse-integer )的所有1032个测试用例,也如关于一样。


/**
 * @param {number} x
 * @return {number}
 */
var reverse = function(x) {
    let oldNum = x, newNum = 0, digits = 0, negativeNum = false;
    if(oldNum < 0){
        negativeNum = true;
    }
    
    let absVal = Math.abs(x);
    while(absVal != 0){
        let r = Math.trunc(absVal % 10);        
        newNum = (newNum*10) + r; digits++;
        absVal = Math.floor(absVal/10);
    }
    if( !(newNum < Number.MAX_VALUE && newNum >= -2147483648 && newNum <= 2147483647)){
        return 0;    
    }
    return negativeNum ? -newNum :newNum;   
};

先前的答案由同一用户发布(未注册)。考虑一下这个。

答案 11 :(得分:0)

以下是用JS(Javascript编码)的解决方案,它已通过Leetcode成功解决了所有问题( https://leetcode.com/problems/reverse-integer )的所有1032个测试用例,也如关于一样。


/**
 * @param {number} x
 * @return {number}
 */
var reverse = function(x) {
    let oldNum = x, newNum = 0, digits = 0, negativeNum = false;
    if(oldNum < 0){
        negativeNum = true;
    }
    
    let absVal = Math.abs(x);
    while(absVal != 0){
        let r = Math.trunc(absVal % 10);        
        newNum = (newNum*10) + r; digits++;
        absVal = Math.floor(absVal/10);
    }
    if( !(newNum < Number.MAX_VALUE && newNum >= -2147483648 && newNum <= 2147483647)){
        return 0;    
    }
    return negativeNum ? -newNum :newNum;   
};

答案 12 :(得分:0)

简单得多的解决方案。确保间歇结果不超过INT_MAX或不超过INT_MIN

int reverse(int x) {

    int y = 0;

    while(x != 0) {

        if ( (long)y*10 + x%10 > INT_MAX || (long)y*10 + x%10 < INT_MIN) {

            std::cout << "overflow occurred" << '\n'
            return 0;
        }

        y = y*10 + x%10;
        x = x/10;   
    }

    return y;
}

答案 13 :(得分:0)

此Java解决方案将起作用:

class Solution {
    public int reverse(int x) {
        long rev = 0, remainder = 0;
        long number = x;

        while (number != 0) {
            remainder = number % 10;
            rev = rev * 10 + remainder;
            number = number / 10;
        }
        if (rev >= Integer.MAX_VALUE || rev <= Integer.MIN_VALUE || x >= Integer.MAX_VALUE || x <= Integer.MIN_VALUE)
            return 0;
        else
            return (int) rev;

    }
}

答案 14 :(得分:0)

请注意输入是否为负

public int reverse(int x) 
{

        long result = 0;
        int res;
        int num = Math.abs(x);

        while(num!=0)
        {
            int rem = num%10;
            result = result *10 + rem;
            num = num / 10;
        }

    if(result > Integer.MAX_VALUE || result < Integer.MIN_VALUE) 
    {
        return 0;
    } 
    else 
    {
        res = (int)result;
        return x < 0 ? -res : res;
    }

}

答案 15 :(得分:0)

这是JavaScript解决方案。

/**
 * @param {number} x
 * @return {number}
 */
var reverse = function(x) {
    var stop = false;
    var res = 0;
    while(!stop){
        res = res *10 + (x % 10);
        x = parseInt(x/10);
        if(x==0){
            stop = true;
        }
    }
    return (res <= 0x7fffffff && res >= -0x80000000) ? res : 0
};

答案 16 :(得分:0)

解决方案在Swift 4.0中(参考来自https://leetcode.com/problems/reverse-integer/description/的问题)

var randomNumberResults = Int32()


@IBOutlet weak var TopLabel: UILabel!

@IBAction func arc4(_ sender: Any) {
      randomNumberResults = Int32(arc4random_uniform(2))
}

@IBAction func LeftButton(_ sender: Any) {
    print(randomNumberResults)
    if randomNumberResults == 0 {
        TopLabel.text = "Right!"
    } else {
        TopLabel.text = "Wrong"
    }
}



@IBAction func RightButton(_ sender: Any) {
    print(randomNumberResults)
    if randomNumberResults == 1 {
        TopLabel.text = "Right!"
    } else {
        TopLabel.text = "Wrong"
    }

}

答案 17 :(得分:0)

public static int reverse(int x) {
  boolean pos = x >= +0;
  int y = (pos) ? x : -x;
  StringBuilder sb = new StringBuilder(
      String.valueOf(y));
  sb.reverse();
  int z = Integer.parseInt(sb.toString());
  return pos ? z : -z;
}

public static void main(String[] args) {
  for (int i = -10; i < 11; i++) {
    System.out.printf("%d r= '%d'\n", i, reverse(i));
  }
}

输出

-10 r= '-1'
-9 r= '-9'
-8 r= '-8'
-7 r= '-7'
-6 r= '-6'
-5 r= '-5'
-4 r= '-4'
-3 r= '-3'
-2 r= '-2'
-1 r= '-1'
0 r= '0'
1 r= '1'
2 r= '2'
3 r= '3'
4 r= '4'
5 r= '5'
6 r= '6'
7 r= '7'
8 r= '8'
9 r= '9'
10 r= '1'

您是否注意到10和-10的反转?还是20?你可以只返回一个String,例如

public static String reverse(int x) {
  boolean pos = x >= +0;
  int y = (pos) ? x : -x;
  StringBuilder sb = new StringBuilder(
      String.valueOf(y));
  sb.reverse();
  if (!pos) {
    sb.insert(0, '-');
  }
  return sb.toString();
}

public static void main(String[] args) {
  for (int i = -10; i < 11; i++) {
    System.out.printf("%d r= '%s'\n", i, reverse(i));
  }
}

按照我的预期工作。

答案 18 :(得分:0)

这个适用于Java的代码可以是: -

public class Solution {
    public int reverse(int x) {

        int r;
        long s = 0;

        while(x != 0)
       {
            r = x % 10;

            s = (s * 10) + r;

            x = x/10;
        }
        if(s >= Integer.MAX_VALUE || s <= Integer.MIN_VALUE) return 0;
        else
            return (int)s;  
    }
}

答案 19 :(得分:0)

这里我们将使用long来处理溢出:

public class Solution {
 public int reverse(int A) {
    // use long to monitor Overflow
    long result = 0;
    while (A != 0) {
        result = result * 10 + (A % 10);
        A = A / 10;
    }
    if (result > Integer.MAX_VALUE || result < Integer.MIN_VALUE) {
        return 0;
    } else {
        return (int) result;
    }
 }
}

答案 20 :(得分:0)

public class Solution {
    public int Reverse(int x) {

            var sign = x < 0 ? -1 : 1;

            var reverse = 0;

            if (x == int.MinValue)
            {
                return 0;
            }
            x = Math.Abs(x);

            while(x > 0)
            {
                var remainder = x % 10;

                if (reverse > ((int.MaxValue - remainder)/10))
                {
                    return 0;
                }

                reverse = (reverse*10) + remainder;

                x = x/10;
            }

            return sign * Convert.ToInt32(reverse);

    }
}

答案 21 :(得分:0)

public class Solution {
    /**
     * OVERFLOW
     * @param x
     * @return
     */
    public int reverse(int x) {
        int sign = x>0? 1: -1;
        x *= sign;
        int ret = 0;
        while(x>0) {
            ret *= 10;
            if(ret<0 || x>10&&ret*10/10!=ret) // overflow
                return 0;

            ret += x%10;
            x /= 10;
        }
        return ret*sign;
    }

    public static void main(String[] args) {
        assert new Solution().reverse(-2147483412)==-2147483412;
    }
}

答案 22 :(得分:0)

使用字符串存储反向,然后打印或使用long或BigInt

答案 23 :(得分:0)

如果要求返回32位int,并且仍然需要知道是否存在溢出,则可以使用标志作为额外参数。如果您使用的是c或c ++,则可以使用指针来设置标志,或者在Java中,您可以使用数组(因为Java对象通过值传递)。

Java示例:

public class Solution {

     public static int reverse(int x, Boolean[] overflowed) {
            int ret = 0;
            boolean zero = false;
            boolean inputIsNegative = x < 0;
            while (!zero) {
                ret = ret * 10 + (x % 10);
                x /= 10;
                if(x == 0){
                    zero = true;
                }
            }
            //Set the flag
            if ( (inputIsNegative && (ret > 0)) || ((!inputIsNegative) && (ret < 0)))
                overflowed[0] = new Boolean(true);
            else
                overflowed[0] = new Boolean(false);
            return ret;
        }

    public static void main(String[] args) {
        int s = 1000000004;
        Boolean[]  flag = {null};
        System.out.println(s);
        int n = reverse(s,flag); //reverse() will set the flag.
        System.out.println(flag[0].booleanValue() ? "Error: Overflow": n );

    }
}

请注意,如果反转的数字对于32位整数而言太大,则将设置该标志。 希望这会有所帮助。

答案 24 :(得分:-2)

请注意,以前的解决方案不适用于输入:1000000045 试试这个:

public int reverse(int A) {
    int reverse=0;
    int num=A;
    boolean flag=false;
    if(A<0)
    {
    num=(-1)*A;
    flag=true;
    }

    int prevnum=0;
    while(num>0)
    {
        int currDigit=num%10;
        reverse=reverse*10+currDigit;

    if((reverse-currDigit)/10!=prevnum)
            return 0;
        num=num/10;  
        prevnum=reverse;
    }

    if(flag==true)
   reverse= reverse*-1;
return reverse;
}