LeetCode 29——兩數相除
阿新 • • 發佈:2018-10-26
urn https 處理 image 循環 繼續 移位操作 div labs 2^0 $ && $ 4 < 3*2^1$,2 的第二高次系數為 1。我們循環進行這個過程,直到最後的數小於除數為止,這些除數前面所有系數的和即為所求。
1. 題目
2. 解答
2.1. 方法一
題目要求不能使用乘法、除法和除余運算,但我們可以將除法轉移到對數域。
$$ \frac{a}{b} = e^{\frac{lna}{lnb}} = e^{lna - lnb}$$
這樣就轉化為指數、對數和減法運算了。因為只能對正整數取對數,因此我們首先要將兩個數都取絕對值,最後再加上符號。
同時,題目要求只能存儲 32 位有符號整數,因此,當數據大於上邊界時,需要進行特殊處理。
class Solution { public: int divide(int dividend, int divisor) { if(dividend == 0) return 0; double a = fabs(dividend); double b = fabs(divisor); long result = exp(log(a) - log(b)); if ((dividend < 0) ^ (divisor < 0)) result = -result; if (result > INT_MAX) result = INT_MAX; return result; } };
2.2. 方法二
利用移位操作。看下面的例子:
$$ 10 \implies 2^1 * 3 + 2^0 * 3 \to \frac{10} {3} = 2^1 + 2^0 = 3$$
$$ 10 \implies 2^2 * 2 + 2^0 * 2 \to \frac{10} {2} = 2^2 + 2^0 = 5$$
$$ 10 \implies 2^3 * 1 + 2^1 * 1 \to \frac{10} {3} = 2^3 + 2^1 = 10$$
我們可以對被除數進行分解。以 10 和 3 為例,首先我們確定 3 的最高次系數,$ 10 > 32^1 $ && $ 10 < 32^2$,因此最高次系數為 2。然後我們用 10 減去 $32^1$,繼續進行剛才的過程,$ 4 > 3
class Solution { public: int divide(int dividend, int divisor) { long a = labs(dividend); // long 型數據占 8 個字節,labs() 函數對 long 求絕對值 long b = labs(divisor); long temp = b; long result = 0; long cnt = 1; while (a >= b) { cnt = 1; temp = b; while (a >= (temp << 1)) { temp = temp << 1; cnt = cnt << 1; // 表征除數前面的各次系數 } a -= temp; result += cnt; } if ((dividend < 0) ^ (divisor < 0)) result = -result; if (result > INT_MAX) result = INT_MAX; // INT_MAX = 2^32 - 1 return result;*/ } };
獲取更多精彩,請關註「seniusen」!
LeetCode 29——兩數相除