Problem 29

Divide Two Integers

Posted by Ruizhi Ma on July 16, 2019

问题描述

https://leetcode.com/problems/divide-two-integers/

解决思路

这道题不可以用除法,不可以用取模运算。举例35和3,思路如下:
3«0,3
3«1,6
3«2,12
3«3,24
3«4,48.
此时48>35,所以只能左移3次到24,38等于24,留下8.此时35-24=11 3«0,3
3«1,6
3«2,12
此时12>11,所以只能左移1次到6,3
2等于6,留下2,加上上一次的8,得到10.此时11-6=5
3«0,3
3«1,6
此时6>5,所以只能左移0次到3,3*1等于3,留下1,加上上一次的10,得到11.此时5-3=2
3«0,3
此时3>2,跳出循环,取上一次11作为结果。

代码

class Solution {
    public int divide(int dividend, int divisor) {
        //corner case
        if(divisor == 0) return Integer.MAX_VALUE;
        if(dividend == Integer.MIN_VALUE){
            //in this condition, the result will be overflow since 2^31 -1 is the max value of positive number, and the min value of negative number is -2^32. Then -2^32 / -1 will be out of the range.
            if(divisor == -1) return Integer.MAX_VALUE;
            else if(divisor == 1) return Integer.MIN_VALUE;
        }
        
        //to avoid overflow
        long divd = (long)dividend;
        long divs = (long)divisor;
        
        //convert dividend and divisor to positive numbers to process together
        int sign = 1;
        if(divd < 0){
            divd = -divd;
            sign = -sign;
        }
        if(divs < 0){
            divs = - divs;
            sign = -sign;
        }
        
        //to calculate the res
        int res = 0;
        while(divd >= divs){
            int shift = 0;
            while(divd >= (divs << shift)){
                shift++;
            }
            //res represent how many divs contains in divd (the reslut of divd / divs). Also it need to be added with former res after every loop
            //shift need to minus 1 since it was added one more time
            res += 1 << (shift - 1);
            //this represents divd - (divd / divs)
            divd -= divs<< (shift - 1);
        }
        
        return sign * res;  
    }
}

复杂度分析

时间复杂度:O(n^2)
空间复杂度:O(1)