簡體   English   中英

反向整數leetcode——如何處理溢出

[英]Reverse Integer leetcode -- how to handle overflow

問題是:反轉整數的數字。

示例 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 所以如果我們不能使用異常,這個解決方案仍然不能解決溢出問題。 這里有什么幫助嗎?(雖然有提示:添加一個額外的參數,但我仍然無法弄清楚我應該添加什么參數)

不需要除 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;
}

上面大多數有一個小問題的答案是 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;
        }
    }

蟒蛇版本

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

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

這是一個老問題,但無論如何,讓我也試試吧! 我剛剛在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;
}

您可以使用 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;
    }
}

我對這個問題的解決方案是將輸入的整數轉換為 c 字符串,那么一切都會很容易。

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

};

這有效:

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

我試圖提高性能一點,但我能想出的是:

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

它的 C# 等價物在我的機器上運行速度比第一個版本快 5%,但他們的服務器說它更慢,這是不可能的——我在這里去掉了額外的函數調用,否則它基本上是一樣的。 根據語言(C# 或 Java)的不同,它使我在 60-30% 之間。 也許他們的基准測試代碼不是很好 - 如果您提交多次 - 結果時間變化很大。


Swift 4.0 中的解決方案(參考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)!

}

昨晚,我嘗試了同樣的問題,我在 python 中找到了一個簡單的解決方案,如下所示,在檢查數字類型正數或負數之后,雖然我在不同的部分嘗試了它們,但我已經轉換了負數轉換為正數,在返回反向數之前,我已將數字轉換為負數。

對於溢出的處理,我只是簡單地檢查了我們的 32 位有符號數的上限和數的下限,它接受了我的回答,謝謝。

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
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? 例如,您可以只返回一個字符串

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

按我的預期工作。

如果您需要返回一個 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 位整數來說太大,則將設置標志。 希望這可以幫助。

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

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

    }
}

這里我們將使用 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;
    }
 }
}

那么這個合適的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;  
    }
}

我的解決方案不使用 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;
    }

}

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

注意輸入是否為負

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

}

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;

    }
}

更簡單的解決方案。 確保間歇性結果不超過 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;
}

這是用 JS 編碼的解決方案(Javascript,它已經成功通過了 Leetcode 中針對該問題的所有 1032 個測試用例( https://leetcode.com/problems/reverse-integer ),也正如問題中所問的一樣。


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

這是用 JS 編碼的解決方案(Javascript,它已經成功通過了 Leetcode 中針對該問題的所有 1032 個測試用例( https://leetcode.com/problems/reverse-integer ),也正如問題中所問的一樣。


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

較早的答案是由同一用戶(未注冊)發布的。 考慮一下這個。

發布了幾個很好的解決方案。 這是我的 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;
};

我讓所有 1032 個案例都可以在 python 中工作,我不知道如何刪除多個 0,例如 100、1000、10000 等,因此我多次使用我的 if 語句哈哈。

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

提取第一個數字並將 x 除以 10 直到 x 等於 0。因此整數將被標記為它的數字。 每個提取的值將在總和乘以 10 后加上總和值。因為添加一個新數字意味着在總和值上添加一個新的 10。 還添加了 if 塊以檢查任何數據損壞,因為在第 9 位之后數據將被損壞。

通過了 1032 / 1032 個測試用例。

狀態:接受

運行時間:3 毫秒

內存使用:38 MB

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

請注意,以前的解決方案不適用於輸入: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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM