CSnerd
CSnerd

Reputation: 2229

Reverse Integer leetcode -- how to handle overflow

The problem is: Reverse digits of an integer.

Example1: x = 123, return 321

Example2: x = -123, return -321

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?

Throw an exception? Good, but what if throwing an exception is not an option? You would then have to re-design the function (ie, add an extra parameter).

The solution from the website I search is:

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));
    }

}

However when s = 1000000003, the console prints -1294967295 instead of 3000000001. So this solution still does not solve the overflow problem if we cannot use exception. Any help here?(Although there is a hint: add an extra parameter, I still cannot figure out what parameter I should add)

Upvotes: 11

Views: 34814

Answers (29)

Kartik Verma
Kartik Verma

Reputation: 1

    def reverse(self, x: int) -> int:
        if x<=-2**31 or x>=2**31-1:
            
            return 0
        else:
            result = 0
            number = x
            number = abs(number)
            while (number) > 0:
                newNumber = number % 10
                result = result * 10 + newNumber
                number = (number // 10)

            if x<0:
                result = "-"+str(result)
                if int(result)<=-2**31:
                    return 0
                return result
            else:
                if result>=2**31-1:
                    return 0
                return result
if __name__ == '__main__':
    obj = Solution()
    print(obj.reverse(1534236469))

Upvotes: 0

Rohit Chaurasiya
Rohit Chaurasiya

Reputation: 486

Public int reverse(int A) {
        int N, sum = 0;
        int rem = 0;
        boolean flag = false;
        int max = Integer.MAX_VALUE;
        int min = Integer.MIN_VALUE;

        if (A < 0) {
            flag = true;
            A = A * -1;} // 123 // 10 1
        while (A > 0) {
            rem = A % 10;
            if (flag == true) {
                if ((min + rem) / 10 > -sum) {
                    return 0;}}else{
                if ((max - rem) / 10 < sum) {
                    return 0;}}
            sum = (sum * 10) + rem;
            A = A / 10;}
        return (flag == true) ? —sum : sum;}}
#java #Algo

Upvotes: 0

g&#252;ven seckin
g&#252;ven seckin

Reputation: 99

 public static int reverse(int x) {

        if (x == 0) return 0;
        int sum = 0;
        int y = 0;
        while (x != 0) {
            int value = (x % 10);
            x = x - value;
            y = sum;
            sum = (sum * 10) + value;
            if(sum / 10 != y) return 0;
            x = x / 10;
        }
        return sum;
    }

Extracting the first digit and dividing x to ten until x will be equal to 0. Therefore integer will be tokenized its digits. Every extracted value will be adding the sum value after multiplying the sum by 10. Because adding a new digit means that adding a new 10th to the sum value. Also added if block to check any corruption of data because after 9th digit data will be corrupted.

1032 / 1032 test cases passed.

Status: Accepted

Runtime: 3 ms

Memory Usage: 38 MB

Upvotes: 0

KingLarry007
KingLarry007

Reputation: 1

I got all 1032 cases to work in python, I don't know how to remove multiple 0's such as 100, 1000, 10000 etc thus I used my if statement multiple times lol.

class Solution:
def reverse(self, x: int) -> int:
        string = ""
        y = str(x)
        ab = list(reversed(y))

        if len(ab) > 1 and ab[0] == "0":
            ab.remove("0")
            if len(ab) > 1 and ab[0] == "0":
                ab.remove("0")
                if len(ab) > 1 and ab[0] == "0":
                    ab.remove("0")
                    if len(ab) > 1 and ab[0] == "0":
                        ab.remove("0")
                        if len(ab) > 1 and ab[0] == "0":
                            ab.remove("0")

        if ab[-1] == "-":
            ab.remove("-")
            ab.insert(0, "-")

        for i in ab:
            string += i

        if int(string) > 2**31 - 1 or int(string) < -2**31:
            return 0
        
        return string

Upvotes: 0

Himanshu sharma
Himanshu sharma

Reputation: 21

you can try this code using strings in 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;
    }
}

Upvotes: 2

di0nys1s
di0nys1s

Reputation: 1

There are several good solutions posted. Here is my JS solution:

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;
};

Upvotes: 0

Yeasin Arafath
Yeasin Arafath

Reputation: 384

Last night, i have tried this same problem and i have found a simple solution in python, which is given below, here after checking the number type positive or negative, though i have tried in different section for both of them, i have convert the negative number into positive and before returning the reverse number, i had converted the number into negative.

For handling overflow, i have just simply checked with the upper limit of our 32-bit signed number and lower limit of the number, and it accepted my answer, thank you.

class Solution:
    def reverse(self, x: int):
        reverse = 0
        if x > 0:
            while x != 0:
                remainder = x % 10
                if reverse > (2147483647/10):
                    return 0
                reverse = reverse * 10 + remainder
                x = int(x / 10)
            return reverse

        elif x < 0:
            x = x * (-1)
            while x != 0:
                remainder = x % 10
                if reverse > ((2147483648)/10):
                    return 0
                reverse = reverse * 10 + remainder
                x = int(x / 10)
            reverse = reverse * (-1)
            return reverse

        else: 
            return 0

Upvotes: 1

Manisha Sinha
Manisha Sinha

Reputation: 11

Here is the solution coded in JS(Javascript, it has passed all the 1032 test cases successfully in Leetcode for the problem (https://leetcode.com/problems/reverse-integer), also as asked in the question about the same.


/**
 * @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;   
};

The earlier answer was posted by the same user (unregistered). Consider this one.

Upvotes: 0

Manisha Sinha
Manisha Sinha

Reputation: 1

Here is the solution coded in JS(Javascript, it has passed all the 1032 test cases successfully in Leetcode for the problem (https://leetcode.com/problems/reverse-integer), also as asked in the question about the same.


/**
 * @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;   
};

Upvotes: 0

Xgh05t
Xgh05t

Reputation: 240

This is an old question, but anyway let me have a go at it too! I just solved it on leetcode. With this check, you never hit the overflow/ underflow in either direction, and I think the code is more concise than all the listed codes. It passes all test cases.

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;
}

Upvotes: 5

FoxRiver
FoxRiver

Reputation: 73

Much simpler solution. Ensure that intermittent result does not exceed INT_MAX or get below 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;
}

Upvotes: 0

Pratibha Yadav
Pratibha Yadav

Reputation: 1

This solution in Java will work:

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;

    }
}

Upvotes: 0

jeevjyot singh chhabda
jeevjyot singh chhabda

Reputation: 637

Taking care if the input is negative

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;
    }

}

Upvotes: 0

liupu
liupu

Reputation: 1

here is the JavaScript solution.

/**
 * @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
};

Upvotes: 0

Noy Miran
Noy Miran

Reputation: 1

Note that there are previous solutions that do not work for input: 1000000045 try this:

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;
}

Upvotes: -3

redEyeProgrammer
redEyeProgrammer

Reputation: 206


Solution In Swift 4.0 (in reference to problem from https://leetcode.com/problems/reverse-integer/description/)

func reverse(_ x : Int) -> Int {

    var stringConversion = String(x)
    var negativeCharacter = false
    var finalreversedString = String()
    let signedInt = 2147483647 //Max for Int 32
    let unSignedInt = -2147483647 // Min for Int 32

    if stringConversion.contains("-"){
        stringConversion.removeFirst()
        negativeCharacter = true
    }

    var reversedString = String(stringConversion.reversed())
    if reversedString.first == "0" {
        reversedString.removeFirst()
    }
    if negativeCharacter {
        finalreversedString = "-\(reversedString)"
    } else {
        finalreversedString = reversedString
    }

    return  (x == 0 || Int(finalreversedString)! > signedInt || Int(finalreversedString)! < unSignedInt) ?  0 :  Int(finalreversedString)!

}

Upvotes: 1

user3366372
user3366372

Reputation: 371

There's no need for any data type other than int. Just make sure when there's an operation that increases a number, reversing the operation should give you the previous number. Otherwise, there's overflow.

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;
}

Upvotes: 24

Gemini Jain
Gemini Jain

Reputation: 61

My solution without using long:

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;
    }

}

Upvotes: 0

Abhisek Mazumdar
Abhisek Mazumdar

Reputation: 1

Well This Suitable Code in Java Can be:-

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;  
    }
}

Upvotes: 0

Jiaji Li
Jiaji Li

Reputation: 1269

Above most of the answers having a trivial problem is that the int variable possibly might overflow. You can try this : x = -2147483648 as parameter. There has an easy way to solve the problem. Convert x to long, and check if the result >= Integer.MAX_VALUE, otherwise return 0. The solution passed all test cases on https://leetcode.com/problems/reverse-integer/

This is a java version.

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# version

    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 version

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

Upvotes: 11

Aakarsh Gupta
Aakarsh Gupta

Reputation: 205

Here we will use long to handle the the over flow:

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;
    }
 }
}

Upvotes: 0

Zar Shardan
Zar Shardan

Reputation: 5921

This works:

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; 
    }
}

I tried to improve the performance a bit but all I could come up with was this:

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

        long tmp = x;
        long res = 0;

        if(x>0){
            while(tmp >= 10){
                res += tmp%10;
                res*=10;
                tmp=tmp/10;          
            }  
        }
        else{
            while(tmp <= -10){
                res += tmp%10;
                res*=10;
                tmp=tmp/10;          
            }  
        }

        res+=tmp;

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

Its C# equivalent runs 5% faster than the 1st version on my machine, but their server says it is slower, which can't be - I got rid of extra function call here, otherwise it is essentially the same. It places me between 60-30% depending on the language (C# or Java). Maybe their benchmarking code is not very good - if you submit several times - resulting times vary a lot.

Upvotes: 1

nimmi chhabra
nimmi chhabra

Reputation: 11

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);

    }
}

Upvotes: 0

Apurva Kumar Sinha
Apurva Kumar Sinha

Reputation: 41

This java code handles the overflow condition:

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;
    }
}

Upvotes: 4

Daniel
Daniel

Reputation: 971

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;
    }
}

Upvotes: 0

Charles Wang
Charles Wang

Reputation: 275

My soluton for this problem is to convert integer inputed to c-string, then everthing will be easy.

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);
}

};

Upvotes: 1

Vikram Bhat
Vikram Bhat

Reputation: 6246

Use string to store the reverse and then print or use long or BigInt

Upvotes: 0

suh
suh

Reputation: 194

If you are required to return a 32 bit int, and still need to know if there was an overflow perhaps you could use a flag as an extra parameter. If you were using c or c++ you could use pointers to set the flag, or in Java you can use an array (since Java objects pass by value).

Java example:

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 );

    }
}

Notice if the reversed number is too large for a 32 bit integer the flag will be set. Hope this helps.

Upvotes: 0

Elliott Frisch
Elliott Frisch

Reputation: 201437

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));
  }
}

Outputs

-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'

Did you notice the reverse of 10 and -10? Or 20? You could just return a String, for example

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));
  }
}

Works as I would expect.

Upvotes: 0

Related Questions