LeetCode-29

楚仙子發表於2020-11-30

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,2311]。本題中,如果除法結果溢位,則返回 2 31 − 1 2^{31} − 1 2311

思路

  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=bc+d=b(20+21+22+...+2n1+2n)+d
  2. 所以我們要求的商,就可以利用位運算來求
  3. 具體實現方式和細節見程式碼

程式碼如下

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);
    }        
};