整數反轉(ReverseInteger)

Aquan發表於2019-12-19

asd

今天我來寫一下 整數反轉 的這一題,我們先目標把 簡單難度 的題給刷了

題目地址:https://leetcode-cn.com/problems/reverse-i...

題目描述

給出一個 32 位的有符號整數,你需要將這個整數中每位上的數字進行反轉。

  • 栗子 1:
輸入: 123
輸出: 321
  • 栗子 2:
輸入: -123
輸出: -321
  • 栗子 3:
輸入: 120
輸出: 21

注意:
假設我們的環境只能儲存得下 32 位的有符號整數,則其數值範圍為 [$-2^{31}$, $2^{31}-1$]。請根據這個假設,如果反轉後整數溢位那麼就返回 0

來源:力扣(LeetCode)

連結:https://leetcode-cn.com/problems/reverse-i...

著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。

自解

當時看到題目後,第一眼看到的想法就是intString後再轉char[]陣列後迴圈顛倒它的位置,後再轉為int返回,最後自己欠缺考慮=。=沒有考慮邊緣值,和溢位的問題,最後用自己的方法沒有通過,這樣提醒我以後寫程式碼時候要考慮和注意邊緣值還有資料溢位的問題。下面會有正確解法,還是自己的經驗不夠會這樣想著解題。

沒有成功:邊緣值無法通過測試 -2147483648

自己當時的解題思路:

  • 第一步直接判斷排除溢位的-2147483648治標不治本(這樣寫程式碼媽見打)
  • 在判斷一下正負數,用flag記錄下後面返回輸出時候用到
  • 獲取X的絕對值,轉換為String
  • String再轉換為char[]進行迴圈翻轉拼接
  • 最後利用BigDecimal轉換為int,根據flag轉化為應該的正負數輸出(為什麼要用BigDecimal呢,因為別的包裝類都會溢位.....)
  • 唔好學我鴨!

上程式碼

// 邊緣值無法通過測試 -2147483648
public static int reverse(int x) {
    if (String.valueOf(x).equals("-2147483648")) {
        return 0;
    }
    Boolean flag = x>=0 ? true:false;
    String a = String.valueOf(Math.abs(x));
    String temp = "";
    char[] chars = a.toCharArray();
    for (int i=0; i<chars.length; i++) {
        temp = chars[i] + temp;
    }
    BigDecimal l = new BigDecimal(temp.trim());
    log.warn(String.valueOf(l));
    if (flag) {
        int result = l.intValue();
        if (String.valueOf(result).equals(String.valueOf(l))) {
            return l.intValue();
        } else {
            return 0;
        }
    } else {
        int result =  l.intValue();
        if (String.valueOf(result).equals(String.valueOf(l))) {
            return result * -1;
        } else {
            return 0;
        }
    }
}

正解

後面看了官方的題解後,是需要考慮是否溢位。

注意點:

  1. 如果 temp = rev * 10 + pop 導致溢位,那麼一定會有 rev >= (Integer.MAX_VALUE / 10)
  2. 如果 rev > (Integer.MAX_VALUE / 10) ,那麼 temp = rev * 10 + pop 一定會溢位
  3. 如果 rev == (Integer.MAX_VALUE / 10) ,那麼只要 pop > 7,temp = rev * 10 + pop 就會溢位

理解思路:

  • 先要理解Integer的溢位,大於Integer.MAX_VALUE或者小於Integer.MIN_VALUE就會報錯
  • 下面首先把x判斷是否為 0,不是就先進行%餘操作得到pop
  • x為什麼要x /= 10 就是 x = x / 10 這裡就是要進行翻轉的關鍵了,看一下下面的一段程式碼 栗子
// 假設我們輸入的是12345,第一個迴圈
int rev = 0; //用來儲存最後的結果
int x = 12345;
int pop = 12345 % 10; // pop = 5 (獲取到了個位數)
x /= 10; // (12345 / 10) = 1234 (int沒有小數自動取整)
rev = rev * 10 + pop; // 0 * 10 + 5 = 5 (rev的值為5)

// 第二個迴圈 (x=1234,rev=5)
int pop = x % 10; // pop = 4
x /= 10; // (1234 / 10) = 123
rev = rev * 10 + pop; // 5 * 10 + 4 = 54 (rev的值為54)
// 沒錯這裡已經翻轉了2個數了後面的也是同理
.....
  • 正負數都一樣的

程式碼:

public static int reverseTwo(int x) {
    int rev = 0;
    while (x != 0) {
        int pop = x % 10;
        x /= 10;
        if (rev > Integer.MAX_VALUE/10 || (rev == Integer.MAX_VALUE / 10 && pop > 7)) return 0;
        if (rev < Integer.MIN_VALUE/10 || (rev == Integer.MIN_VALUE / 10 && pop < -8)) return 0;
        rev = rev * 10 + pop;
    }
    return rev;
}

總結

這就是這次的整數翻轉了,希望大家不要學我開始的思路解法,寫程式碼時候大家得考慮 溢位 的問題哦。

長按關注喔~

本作品採用《CC 協議》,轉載必須註明作者和本文連結

愛敲程式碼的貓

相關文章