asd
今天我來寫一下 整數反轉 的這一題,我們先目標把 簡單難度 的題給刷了
題目描述
給出一個 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...
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
自解
當時看到題目後,第一眼看到的想法就是int
轉String
後再轉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;
}
}
}
正解
後面看了官方的題解後,是需要考慮是否溢位。
注意點:
- 如果
temp = rev * 10 + pop
導致溢位,那麼一定會有rev >= (Integer.MAX_VALUE / 10)
- 如果
rev > (Integer.MAX_VALUE / 10)
,那麼temp = rev * 10 + pop
一定會溢位 - 如果
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 協議》,轉載必須註明作者和本文連結