文章标题

Divide two integers without using multiplication, division and mod operator.
思路:1.先将被除数和除数转化为long的非负数,注意一定要为long,因为Integer.MIN_VALUE的绝对值超出了Integer的范围。
2.常理:任何正整数num都可以表示为num=2^a+2^b+2^c+…+2^n,故可以采用2^a+2^b+2^c+…+2^n来表示商,即dividend=divisor*(2^a+2^b+2^c+…+2^n),(a,b,c,….m互不相等,且最大为31,最小为0)。而商的最大值为Integer.MIN_VALUE的绝对值,商最多有32个2的指数次相加,故时间复杂度为常数。
3.divisor*2^a用计算机表示为divisor<

class Solution {
public:
    long long internalDivide(unsigned long long dividend, unsigned long long divisor) {
        if (dividend < divisor) {
            return 0;
        }

        long long result = 1;
        unsigned long long tmp = divisor, left;

        while (tmp <= dividend) {
            left = dividend - tmp;
            tmp <<= 1;

            if (tmp > dividend) {
                break;
            }
            else {
                result <<= 1;
            }
        }

        return result + internalDivide(left, divisor);
    }

    int divide(int dividend, int divisor) {
        unsigned long long _dividend = abs((long long)dividend), 
            _divisor = abs((long long)divisor);
        bool positive = ((dividend >= 0) && (divisor > 0)) || ((dividend <= 0) && (divisor < 0));

        return positive ? internalDivide(_dividend, _divisor) : (-1) * internalDivide(_dividend, _divisor);
    }
};

[java] view plaincopy在CODE上查看代码片派生到我的代码片
public class Solution {
public int divide(int dividend, int divisor) {

    boolean positive = true;  
    if((dividend>0&&divisor<0)||(dividend<0&&divisor>0))  
        positive = false;  
    long did=dividend>=0?(long)dividend:-(long)dividend;  
    long dis=divisor>=0?(long)divisor:-(long)divisor;  

    long quotients = positiveDivide(did, dis);  
    if (!positive)  
        return (int)-quotients;  
    return (int)quotients;  
}  

public long positiveDivide(long did, long dis) {  
    long[] array = new long[32];  
    long sum = 0;  
    int i = 1;  
    long quotients = 0;  
    if(dis==1) return did;//为了避免-did=Integer.MIN_VALUE,而dis=1,出现问题  
    for (array[0]=dis; i < 32 && array[i - 1] <= did; i++)   
        array[i] = array[i - 1] << 1;  

    for (i = i - 2; i >= 0; i--) {  
        if (sum <= did - array[i]) {  
            sum += array[i];  
            quotients += 1 << i;  
        }  
    }         
    return quotients;  
}  

}
优化版,减小内存的消耗,不申请动态数组
[java] view plaincopy在CODE上查看代码片派生到我的代码片
public class Solution {
public int divide(int dividend, int divisor) {

    boolean positive = true;  
    if((dividend>0&&divisor<0)||(dividend<0&&divisor>0))  
        positive = false;  
    long did=dividend>=0?(long)dividend:-(long)dividend;  
    long dis=divisor>=0?(long)divisor:-(long)divisor;  

    long quotients = positiveDivide(did, dis);  
    if (!positive)  
        return (int)-quotients;  
    return (int)quotients;  
}  

public long positiveDivide(long did, long dis) {  
    long sum = 0;  
    long quotients = 0;  
    if(dis==1) return did;//为了避免-did=Integer.MIN_VALUE,而dis=1,出现问题  

    //sum从divisor*2^31的开始加起,不能加则试试加上divisor*2^30,  
    //若不能则试试divisor*2^29,依此类推  
    for (int i = 31; i >= 0; i--) {  
        long temp=dis<<i;//该式为divisor*2^a  

         /* sum+temp <= dividend , 则说明dividend大于divisor*(2^m+...+2^i),m最大为31。

那么2的i次方这个结果可以保留。*/
if (sum <= did - temp) {
sum += temp;
quotients += 1 << i;//2^i
}
}
return quotients;
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值