LeetCode 7.整數(shù)反轉(zhuǎn)
題目:
給你一個(gè) 32 位的有符號(hào)整數(shù) x ,返回將 x 中的數(shù)字部分反轉(zhuǎn)后的結(jié)果。
如果反轉(zhuǎn)后整數(shù)超過 32 位的有符號(hào)整數(shù)的范圍 [?231, 231 ? 1] ,就返回 0。
假設(shè)環(huán)境不允許存儲(chǔ) 64 位整數(shù)(有符號(hào)或無符號(hào))。
示例 1:
輸入:x = 123
輸出:321
示例 2:
輸入:x = -123
輸出:-321
示例 3:
輸入:x = 120
輸出:21
示例 4:
輸入:x = 0
輸出:0
提示:
-231 <= x <= 231 - 1
筆者思路
這題比較簡(jiǎn)單,無非就是加減乘除而已,使用乘以10再加新數(shù)字ret = ret * 10 + rem的形式即可。
主要是要考慮對(duì)于一些特殊數(shù)組會(huì)溢出的問題。比如12****8979,這個(gè)數(shù)組反過來很可能就大于INT_MAX了。使用乘以10再加上新數(shù)字的算法,就可能異常。
可以反過來,思考,既然乘以10再加上新數(shù)字的結(jié)果跟INT_MAX比較可能異常,使用INT_MAX減去新數(shù)字再除以10跟原數(shù)字相比即可。
所以代碼如下:
class Solution {
public:
int reverse(int x) {
if(x==INT_MIN)//剔除這個(gè)特殊情況后,x就對(duì)稱了
return 0;
bool f = (x >= 0);//符號(hào)
int ret = 0;
x = f ? x : -x;
while(x > 0){
int rem = x % 10;//余數(shù)
x = x / 10;//新的x
if((INT_MAX - rem) / 10 < ret){//直接算可能溢出,反過來由INT_max計(jì)算出預(yù)計(jì)算出的ret是否滿足
return 0;
}
ret = ret * 10 + rem;//如果沒有上面的排查,這里會(huì)溢出
}
return f ? ret : -ret;
}
};
官方解答
class Solution {
public:
int reverse(int x) {
int rev = 0;
while (x != 0) {
if (rev < INT_MIN / 10 || rev > INT_MAX / 10) {
return 0;
}
int digit = x % 10;
x /= 10;
rev = rev * 10 + digit;
}
return rev;
}
};
官方又了一堆數(shù)學(xué)公式,證明了只需要考慮 (rev < INT_MIN / 10 || rev > INT_MAX / 10)即可。其實(shí)跟我的代碼(INT_MAX - rem) / 10 < ret)是差不多的意思,只是我的代碼這樣免得更多的數(shù)學(xué)思考了。
另外有一點(diǎn),我的算法之所以將負(fù)數(shù)區(qū)分開考慮,是因?yàn)槲覍?shí)在不知道-12除以10到底是余2還是余8還是-2。不過經(jīng)過實(shí)驗(yàn)-12/10=-1......-2。所以官方的解答更為簡(jiǎn)便一些。

浙公網(wǎng)安備 33010602011771號(hào)