學妹發現題目下方還有內容,滑動了網頁。「嗯?這裡有個隱藏提示?」
「哪裡?」我怎麼不知道有這種東西?
「這裡,這個Show Hint
可以點開。」學妹點開後顯示了Beware of overflow when you reverse the integer.
文字。
「哦,我平常都只看題目內容,難怪沒注意到這邊還有這麼多方便的功能,還能找相似問題。」
「學姊知道提示在提醒什麼嗎?」學妹看我注意力跑到別的功能,趕緊把我拉回來。
「啊,因為這個回文題目妳是用兩側比對的做法,所以不會用上這個提示。這個提示適用於把數字翻轉和原數字比對的做法,有個題目剛好就是要求翻轉數字,我拿那個來說明。」
「看到這個了嗎?題目強調是32位元的帶正負整數,最大值是2的31次方少1,當妳加上1反而會變成-2的31次方,因為已經佔用到正負符號的儲存位置了,這就是overflow——溢位問題。」
「那我要怎麼表達更大的數字?」學妹困惑的說。
「那就改用Long,它是64位元,最大值2是63次方少1。不過這個題目希望妳不要用這種方式逃開溢位問題。其實溢位不會很難發現,只要比較運算結果是否合理,就可以抓到溢位。」
「什麼意思?」學妹呢喃著。「運算結果不合理?」
她才聽到溢位大概沒辦法馬上應用吧,我試著舉例說明:「比如:加上正數得到的結果卻小於一開始的數字,乘以10得到的結果卻不是10的倍數,反運算回來後的數字不等於原本的數字等等。這題我會建議先把最小值分開處理,只有它才一拿掉負號就馬上溢位了。」
class Solution {
fun reverse(x: Int): Int {
//2^31 = 2147483648
if (x == -2147483648) return 0
var pow10 = 10
val xAbs = if (x > 0) x else -x
var result = xAbs % 10
var old = result
while (xAbs / pow10 >= 1 && pow10 % 10 == 0) {
result *= 10
result += xAbs / pow10 % 10
if ((result - xAbs / pow10 % 10) / 10 != old) return 0
pow10 *= 10
old = result
}
return if (x > 0) result else -result
}
}