LeetCode-29
29. 兩數相除
給定兩個整數,被除數 d i v i d e n d dividend dividend 和除數 d i v i s o r divisor divisor。將兩數相除,要求不使用乘法、除法和 m o d mod mod 運算子。
返回被除數 d i v i d e n d dividend dividend 除以除數 d i v i s o r divisor divisor 得到的商。
整數除法的結果應當截去 ( t r u n c a t e ) (truncate) (truncate)其小數部分,例如: t r u n c a t e ( 8.345 ) = 8 truncate(8.345) = 8 truncate(8.345)=8 以及 t r u n c a t e ( − 2.7335 ) = − 2 truncate(-2.7335) = -2 truncate(−2.7335)=−2
Example
input |
---|
dividend = 10, divisor = 3 |
output |
3 |
input |
---|
dividend = 10, divisor = 3 |
output |
-2 |
Note
- 例項1: 10 / 3 = t r u n c a t e ( 3.33333.. ) = t r u n c a t e ( 3 ) = 3 10/3 = truncate(3.33333..) = truncate(3) = 3 10/3=truncate(3.33333..)=truncate(3)=3
- 例項2: 7 / − 3 = t r u n c a t e ( − 2.33333.. ) = − 2 7/-3 = truncate(-2.33333..) = -2 7/−3=truncate(−2.33333..)=−2
- 被除數和除數均為 32 位有符號整數。
- 除數不為 0。
- 假設我們的環境只能儲存 32 位有符號整數,其數值範圍是 [ − 2 31 , 2 31 − 1 ] [−2^{31}, 2^{31} − 1] [−231,231−1]。本題中,如果除法結果溢位,則返回 2 31 − 1 2^{31} − 1 231−1。
思路
- 因為 a / b = c . . . d a / b = c ...d a/b=c...d,所以 a = b ∗ c + d = b ∗ ( 2 0 + 2 1 + 2 2 + . . . + 2 n − 1 + 2 n ) + d a = b *c + d = b * ( 2^0 + 2^1 + 2^2 + ... +2^{n-1}+2^ n) + d a=b∗c+d=b∗(20+21+22+...+2n−1+2n)+d
- 所以我們要求的商,就可以利用位運算來求
- 具體實現方式和細節見程式碼
程式碼如下
typedef long long ll;
class Solution {
public:
int divide(int dividend, int divisor) {
int flag = 1;
if(dividend == 0){
return 0;
}
else if((dividend > 0 && divisor <0)||(dividend < 0 && divisor > 0)){
flag = 0;
}
ll a = abs(dividend);
ll b = abs(divisor);
ll ans = div(a,b);
if(flag)
return ans>INT_MAX?INT_MAX:ans;
return -ans;
}
ll div(ll a , ll b)
{
if(a < b)
return 0;
ll count = 1;
ll c = b;
while(a >= c<<1)
{
c<<=1;
count<<=1;
}
return count + div(a-c, b);
}
};