📘 題目敘述
給定一個 32-bit 有號整數 x,請將其數字反轉後回傳。
若反轉後的整數超出 32-bit 有號整數範圍 [-2^31, 2^31 - 1],則回傳 0。
條件限制
-2^31 ≤ x ≤ 2^31 - 1
🧠 解題思路
我的做法是「一位一位反轉數字」,而不是先轉成字串。
整體流程可以分成三件事:
- 從原本的數字
x取出最後一位數字 - 把這一位數字接到新的結果
y後面 - 在每一次接之前,先確認不會發生溢位
所有變數(對應程式碼)
x:目前還沒處理完的原始整數y:目前已經反轉完成的結果digit:從x取出的最後一位數字intmax:32-bit 有號整數最大值2147483647intmin:32-bit 有號整數最小值-2147483648
while (x != 0):逐位處理數字
這個迴圈代表:
- 只要
x還不是 0,就表示還有數字尚未被反轉 - 每一輪迴圈,處理
x的「最後一位」
第一步:取出最後一位數字
int digit = x % 10;
這一行的作用是:透過 mod 10 取得 x 的最後一位數字。
在 C++ 中,若 x 是負數,digit 也會是負的,因此正負數可以用同一套邏輯處理。
第二步:檢查是否會發生溢位(重點)
在真正把 digit 接到 y 後面之前,我會先檢查:
y = y * 10 + digit;
這一步是否會超出 32-bit 有號整數範圍。
情況一:x > 0(處理正數)
if (y > intmax / 10 || (y == intmax / 10 && digit > 7)) {
return 0;
}
若 y > intmax / 10,下一步乘 10 一定會溢位;若 y == intmax / 10,最後一位只能接 0 ~ 7。
情況二:x < 0(處理負數)
else if (y < intmin / 10 || (y == intmin / 10 && digit < -8)) {
return 0;
}
intmin 的最後一位是 -8,若下一步會小於 -2^31 就直接回傳 0。
第三步:安全地更新反轉結果
y = y * 10 + digit;
這一行只會在已經確認不會溢位的情況下執行。
第四步:移除 x 的最後一位
x = (x - digit) / 10;
把剛剛取出的 digit 從 x 中移除,讓下一輪處理新的最後一位數字。
迴圈結束後,當 x == 0,代表所有位數都已經反轉完成,此時 y 就是最終答案。
💻 程式碼實作
class Solution {
public:
int reverse(int x) {
int y = 0;
int sign = 1;
int intmax = 2147483647;
int intmin = -2147483648;
while (x != 0) {
int digit = x % 10;
if (x > 0 && (y > intmax / 10 || (y == intmax / 10 && digit > 7))) {
return 0;
} else if (x < 0 &&
(y < intmin / 10 || (y == intmin / 10 && digit < -8))) {
return 0;
}
y = y * 10 + digit;
x = (x - digit) / 10;
}
return y;
}
};
🔗 題目連結
https://leetcode.com/problems/reverse-integer/