Divide Two Integers

Description

Divide two integers without using multiplication, division and mod operator.

If it is overflow, return MAX_INT.

Tags: Math, Binary Search

思路

题意是让你算两个整型数相除后的结果,如果结果溢出就返回 MAX_INT,但不能使用乘、除、余的操作符,如果是用加减操作符的话肯定会超时哈,这样的话我们就只能想到位操作符了。

首先,我们分析下溢出的情况,也就是当被除数为 Integer.MIN_VALUE,除数为 -1 时会溢出,因为 |Integer.MIN_VALUE| = Integer.MAX_VALUE + 1

然后,我们把除数和被除数都转为 long 类型的正数去做下一步操作,我这里以 223 相除为例子,因为 22 >= 3,我们对 3 进行左移一位,也就是乘 2,结果为 6,比 22 小,我们继续对 6 左移一位结果为 12,还是比 22 小,我们继续对 12 左移一位为 24,比 22 大,这时我们可以分析出,22 肯定比 34 倍要大,4 是怎么来的?因为我们左移了两次,也就是 1 << 2 = 4,此时我们记下这个 4,然后让 22 - 3 * 4 = 10,因为 10 >= 3,对 103 进行同样的操作,我们可以得到 2,此时加上上次的 4,和为 6,也就是 2236 倍要大,此时还剩余 10 - 6 = 4,因为 4 >= 3,所以对 43 进行同样的操作,我们发现并不能对 3 进行左移了,因为 4 >= 3,所以 1 倍还是有的,所以加上最后的 1,结果为 6 + 1 = 7,也就是 22 整除 3 结果为 7

最终,我们对结果赋予符号位即可,根据以上思路来书写如下代码应该不是难事了吧。

class Solution {
    public int divide(int dividend, int divisor) {
        if (dividend == Integer.MIN_VALUE && divisor == -1) {
            return Integer.MAX_VALUE;
        }
        long dvd = Math.abs((long) dividend);
        long dvr = Math.abs((long) divisor);
        int res = 0;
        while (dvd >= dvr) {
            long temp = dvr, multiple = 1;
            while (dvd >= temp << 1) {
                temp <<= 1;
                multiple <<= 1;
            }
            dvd -= temp;
            res += multiple;
        }
        return (dividend < 0) ^ (divisor < 0) ? -res : res;
    }
}

结语

如果你同我们一样热爱数据结构、算法、LeetCode,可以关注我们 GitHub 上的 LeetCode 题解:LeetCode-Solution