LeetCode: Divide Two Integers

题目:
Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.

题目很有意思,要求在不做乘法、除法、取余运算的条件下求两个除数相除的结果。
首先想到的是做减法,用一个变量标记两数相除的结果的正负(两数同号为正,异号为负),然后把除数和被除数取绝对值后做减法运算。用一个变量count表示结果,初始化为0,被除数每减除数一次,count值加一,将相减的结果作为被除数继续运算,直到被除数-除数小于0时跳出循环。算法复杂度为o(n)。代码:

class Solution {
public:
    int divide(int dividend, int divisor) {
        int count=0;
        int mark=0;//用于标记结果为正还是为负
        //把被除数转化为正数
        if(dividend<0) 
        {
            mark++;
            int temp=0-dividend;
            dividend=dividend+temp+temp;
        }
        //把除数转化为正数
        if(divisor<0)
        {
            mark++;
            int temp=0-divisor;
            divisor=divisor+temp+temp;
        }
        while(dividend-divisor>=0)
        {
            dividend-=divisor;
            count++;
        }
        if(mark==1)
        {
            return 0-count;
        }
        return count;
    }
};

但是算法超时了,由于加法和减法具有相同的优先级,所以可以初步判断,仅使用加法和减法的算法是很容易超时的,必须扩展其它的运算。除加、减、乘、除、取余外,C++还有移位运算和逻辑运算,考虑移位运算:左移一位,相当于是乘2;右移一位,相当于是除以2。所以可以用移位运算来降低算法的时间复杂度。在上一个算法的基础上做优化:对除数做左移运算,得到一个再左移一位就会超过被除数的基,并记录左移的位数k,共有k个基,每个基都是2的幂次方。从最大的基开始,将被除数减去这个基,把2的k次方加到结果中,循环结束后即得到结果。算法复杂度为o(logn)。代码:

class Solution {
public:
    int divide(int dividend, int divisor) {

        long int count=0;
        int mark=0;
        //如果被除数是负数
        if(dividend<0)
        {
            mark++;
            dividend=-dividend;
        }
        //如果除数是负数
        if(divisor<0)
        {
            mark++;
            divisor=-divisor;
        }
        if(dividend==0||dividend<divisor) return 0;
        int k=0;//移位位数
        while(divisor<=(dividend>>1))
        {
            divisor=divisor<<1;
            k++;
        }
        //减法计算
        while(k>=0)
        {
            if(dividend>=divisor)
            {
                dividend -= divisor;
                count+=1<<k;
            }
            divisor=divisor>>1;
            k--;
        }
        if(mark==1) return -count;
        return count;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值