29. 两数相除 (龟速乘)

不能使用乘法和除法,所以考虑二分。

最多能除以多少个除数。

a b = a n s \dfrac{a}{b}=ans ba=ans

二分 a n s ans ans

m i d × b ≤ a mid \times b\le a mid×ba

乘法就用龟速乘代替。

时间复杂度: O ( l o g n ) O(logn) O(logn)

因为有可能溢出,所以用long long即可。

比如: − 2 31 − 1 = 2 31 > I N T _ M A X \dfrac{-{2^{31}}}{-1}=2^{31}>INT\_MAX 1231=231>INT_MAX 溢出了,所以都用long long 作为中间变量即可。

参考代码

class Solution {
    int INF = Integer.MAX_VALUE;
    public int divide(int _a, int _b) {
        long a = _a, b = _b;
        boolean flag = false;
        if ((a < 0 && b > 0) || (a > 0 && b < 0)) flag = true;
        if (a < 0) a = -a;
        if (b < 0) b = -b;
        long l = 0, r = a;
        while (l < r) {
            long mid = l + r + 1 >> 1;
            if (mul(mid, b) <= a) l = mid;
            else r = mid - 1;
        }
        r = flag ? -r : r;
        if (r > INF || r < -INF - 1) return INF;
        return (int)r;
    }
    long mul(long a, long k) {
        long ans = 0;
        while (k > 0) {
            if ((k & 1) == 1) ans += a;
            k >>= 1;
            a += a;
        }
        return ans;
    }
}