問題の説明
32 ビットの符号付き整数 xを指定すると、x の各ビットの数字を反転した結果を返します。
逆整数が 32 ビットの符号付き整数の範囲[−231, 231 − 1]を超える場合は、0を返します。
環境が64 ビット整数(符号付きまたは符号なし) の格納を許可していないとします。
例 1
输入:x = 123
输出:321
例 2
输入:x = -123
输出:-321
例 3
输入:x = 120
输出:21
例 4
输入:x = 0
输出:0
問題が解決しました
1. アイデアとアルゴリズム
オーバーフローの問題を考慮しない場合、この質問は非常に単純です。オーバーフローの問題を解決するには 2 つの方法があります。
- 最初のアイデアは、文字列変換によって解決し、 catch を試すことです。
- 2 番目のアイデアは、数学的計算によって解決することです。
文字列変換の効率が低く、より多くのライブラリ関数を使用するため、ソリューションではこの方法を考慮せず、数学的計算によって解決します。
数値 x の各ビットはループによって分解され、新しい値を計算する各ステップで、オーバーフローするかどうかが判断されます。
2 つのオーバーフロー条件があります。
- 1 は、整数の最大値 MAX_VALUEより大きく、
- 1 は、整数の最小値 MIN_VALUE未満です。
現在の計算結果を ans、次のビットを pop とする。
ans * 10 + pop > MAX_VALUEのオーバーフロー条件から判断
- ans > MAX_VALUE / 10があり、追加する pop がまだある場合は、オーバーフローする必要があります
- ans == MAX_VALUE / 10およびpop > 7の場合、オーバーフローする必要があります。7は 2^31 - 1 の 1 桁です。
ans * 10 + pop < MIN_VALUEのオーバーフロー条件から判断
- ans < MIN_VALUE / 10で pop を追加する必要がある場合は、オーバーフローする必要があります
- ans == MIN_VALUE / 10でpop < -8の場合、オーバーフローする必要があります。8は -2^31 の 1 桁です。
2.コード`
class Solution {
public int reverse(int x) {
int ans = 0;
while (x != 0) {
int pop = x % 10;
if (ans > Integer.MAX_VALUE / 10 || (ans == Integer.MAX_VALUE / 10 && pop > 7))
return 0;
if (ans < Integer.MIN_VALUE / 10 || (ans == Integer.MIN_VALUE / 10 && pop < -8))
return 0;
ans = ans * 10 + pop;
x /= 10;
}
return ans;
}
}