(算法分析Week7)Divide Two Integers[Medium]

来源:互联网 发布:林振强 知乎 编辑:程序博客网 时间:2024/06/05 08:02

29.Divide Two Integers

题目来源

Description

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

If it is overflow, return MAX_INT.

题目意思就是计算两个数的除法,但是不能用乘、除和模运算(所以很明显用减法……)

Solution

刚好上学期学了计组,除法在硬件中的实现一般就是用减法实现。可以直接用被除数减去除数直到被除数小于等于0为止,不过仔细观察“减法”过程,发现可以利用移位操作减少循环次数。
举个例子,30÷3,除数3每次移位变成6、12、…,此时商相应左移(从1开始),对应得到1、2、4….,最后把这些数加起来即可得到真正的商值。

30-31) ——> 27-6(1<<1=2) ——> 21-12(2 <<1=4)——>9 - 24(0,结束)此时商是1+2+4 = 7,被除数还剩9重新开始一次循环,9-3(1)——> 6-6(1 << 1 = 2)此时商是1+2 = 3,被除数剩余0,结束商 = 7 + 3 = 10

*如果不是整除也同样适用,例子略

关于溢出的情况,两种
1.除数为0
2.abs(INT_MIN) = INT_MAX + 1,即被除数为 INT_MIN && 除数为-1

Complexity analysis

O(( log N)^2)
内外层循环都是LogN

Code

class Solution {public:    int divide(int dividend, int divisor) {        if (divisor == 0)            return INT_MAX;        if (dividend == INT_MIN&& divisor == -1)            return INT_MAX;        bool sign = true; // 1        if ((dividend < 0 && divisor > 0 ) || (dividend > 0 && divisor < 0 )) {        /*注意符号问题*/            sign = false; //-1        }        long long dvd = labs(dividend);        long long div = labs(divisor);        int result = 0;        while(dvd >= div) {            long long temp = div;            long long re = 1;            while(dvd >= (temp << 1)) {                re <<= 1;                temp <<= 1;            }            dvd -= temp;            result += re;        }        if (sign == true) {            return result;           } else {            return -result;        }    }};

Result这里写图片描述