LeetCode 29. Divide Two Integers

问题链接

LeetCode 29. Divide Two Integers

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

If it is overflow, return MAX_INT.

题目解析

两数相除,不得使用乘法、除法、取模运算。

解题思路

题目限制这么大,很明显是要考察专一的知识点,那是什么呢?神奇的 位运算操作,简单来讲就是 二进制 的运用。

你最初的思路可能是这样子,只运用减法,每次减去除数,最后总能得到结果,没错,但是这样有什么意义呢?我觉得应该可以AC,但也不想去试着写这样的辣鸡代码。一个一个减,多想一下,可不可以多个一起减呢?

举一个简单的例子,求解40÷3,结果为13(忽略余数),如果一个一个减,在第14次减去3的时候可以知道答案是13。这个13可以可以以另一种方式得到,每一个数都有二进制表示,它的含义是什么呢,其实是多个2的幂值相加,这里的13=8+4+1,意味着40=(8*3)+(4*3)+(1*3)···1,所以问题转化为求这多个2的幂值。

具体实现,最初的想法是每次循环减一次(1*除数),现在改进后,每次循环减去(最大2的幂值*除数),通过左移运算,每次将幂值<<1(乘2),求得最大2的幂值后,更新被除数和结果。如何求得最大2的幂值,可参考代码理解。

注意:排除特殊情况,除数为0或者超出int范围。左移运算中,数值范围可能超出int,采用long或者long long都可以。

参考代码

class Solution {
public:
    int divide(int dividend, int divisor) {
        if (!divisor || (dividend == INT_MIN && divisor == -1)) return INT_MAX;
        
        int sign = ((dividend < 0) ^ (divisor < 0)) ? -1 : 1;
        long long dvd = labs(dividend);
        long long dvs = labs(divisor);
        int res = 0;
        while (dvd >= dvs) { 
            long long temp = dvs, multiple = 1;
            while (dvd >= (temp << 1)) {
                temp <<= 1;
                multiple <<= 1;
            }
            dvd -= temp;
            res += multiple;
        }
        return sign == 1 ? res : -res; 
    }
};

参考链接:Detailed Explained 8ms C++ solution


LeetCode All in One题解汇总(持续更新中...)

本文版权归作者AlvinZH和博客园所有,欢迎转载和商用,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.


posted @ 2018-03-25 11:58  AlvinZH  阅读(1144)  评论(0编辑  收藏  举报