題目描述
給出一個 32 位的有符號整數,你需要將這個整數中每位上的數字進行反轉。
假設我們的環境只能存儲得下 32 位的有符號整數,則其數值範圍爲 。請根據這個假設,如果反轉後整數溢出那麼就返回 0。
數據樣例
輸入: 123 輸出: 321
輸入: -123 輸出: -321
輸入: 120 輸出: 21
算法分析
如果是一個字符串,怎麼反轉?使用棧思想,字符順序入棧再出棧,就能得到反轉的字符串。
數字也是同理的,使用棧思想,但是多一步溢出的考慮。
每一位的數字入棧、出棧的過程,可以用代碼表示爲
// x是原數字,rev是反轉後的數字
int x, rev;
// 入棧
int pop = x % 10;
x /= 10;
// 出棧
int temp = rev * 10 + pop; // 這裏有溢出的可能
rev = temp;
可以看到,最後的出棧過程存在溢出的可能性。
處理溢出問題,有兩種思路:
- 找出正負數各自溢出的臨界點
- 利用溢出特性進行反向驗證,語言不好解釋,看代碼更清晰
思路一
找出溢出的臨界點,正負數溢出臨界點分別是:
// 正數溢出臨界點
rev == Integer.MAX_VALUE / 10 && pop > Integer.MAX_VALUE % 10
// 負數溢出臨界點
rev == Integer.MIN_VALUE / 10 && x < Integer.MIN_VALUE % 10
算法代碼:
public int reverse(int x) {
int rev = 0;
while (x != 0) {
int pop = x % 10;
// 正數溢出臨界點
if (rev > Integer.MAX_VALUE / 10 || (rev == Integer.MAX_VALUE && pop > Integer.MAX_VALUE % 10))
return 0;
// 負數溢出臨界點
if (rev < Integer.MIN_VALUE / 10 || (rev == Integer.MIN_VALUE && pop > Integer.MIN_VALUE % 10))
return 0;
x /= 10;
rev = rev * 10 + pop;
}
return rev;
}
思路二
數字計算溢出後得到的結果,再除以 10 是不能得到原值的。
算法代碼:
public int reverse(int x) {
int reverse = 0;
while (x != 0) {
int temp = reverse * 10 + x % 10;
if (temp / 10 != reverse) return 0;// 利用的溢出特性反向驗證
reverse = temp;
x /= 10;
}
return reverse;
}