Leetcode——29. Divide Two Integers

题目

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

If it is overflow, return MAX_INT.

题意理解

实现除法运算,不能使用乘法,除法,模运算

解题思路

需要注意的:
1。 先对异常情况处理,除数是0的,结果大于INT_MAX的。
2。 都转化为正数进行处理
这一步需要注意:转化后有可能结果大于INT_MAX,比如被除数是INT_MIN的。那么可以把转化后的结果声明为long long等,第二个办法就是先做一步把被除数减去除数的运算,排除异常的影响。

3。 转化后,可以逐渐递减,直到小于0,然后计数递减次数来当做结果。这个方法复杂度过高。
另一个方法类似于位运算,每次减去的数都加倍,直到大于被除数,然后再从1开始翻倍递减,中间计数时需要注意累加和翻倍。

Code

第一个超时,第二第三都能AC

class Solution1 {//不用乘除,模运算,求解除法
public:
    int divide(int dividend, int divisor) {
        if(divisor==0) return INT_MAX;
        if(dividend==0) return 0;
        bool sign=1;
        int count=0;//用于计数
        if(dividend<0&&divisor>0||dividend>0&&divisor<0)
            sign=0;

         //(下面的处理忘了处理最小值转化为最大值时会溢出的情况:-2147483648
         if(dividend==INT_MIN||divisor==INT_MIN)
         {
             if(dividend==INT_MIN&&divisor==INT_MIN) return 1;
             if(divisor==INT_MIN) return 0;
             //被除数是最小值,除数不是
             if(divisor<0)
             {
                 dividend=dividend-divisor;//降低dividend(由于都是整数,降低之后肯定不溢出)
                 count++;
             }
             else if(divisor>0)
             {
                dividend=dividend+divisor;//降低dividend(由于都是整数,降低之后肯定不溢出)
                count++; 
             }
         }



        if(dividend<0) dividend=-dividend;
        if(divisor<0) divisor=-divisor;//都转化为正的来处理


        while(dividend>=divisor)
        {
            dividend=dividend-divisor;
            count++;
            if(count==INT_MAX) return INT_MAX;//(这种情况是-2147483648 -1,理应得到2147483648,但是超出范围了,应为2147483647)
        }
        if(sign) return count;
        else return -count;
    }
};//这个解法太慢了!!!

//采用二分法思想
class Solution2 {//不用乘除,模运算,求解除法
public:
    int divide(int dividend, int divisor) {
        if(divisor==0) return INT_MAX;
        if(dividend==0) return 0;
        bool sign=1;
        unsigned int count=0;//用于计数
        int Sum=0;
        if(dividend<0&&divisor>0||dividend>0&&divisor<0)
            sign=0;

         //(下面的处理忘了处理最小值转化为最大值时会溢出的情况:-2147483648
         if(dividend==INT_MIN||divisor==INT_MIN)
         {
             if(dividend==INT_MIN&&divisor==INT_MIN) return 1;
             if(divisor==INT_MIN) return 0;
             //被除数是最小值,除数不是
             if(divisor<0)
             {
                 dividend=dividend-divisor;//降低dividend(由于都是整数,降低之后肯定不溢出)
                 count++;
             }
             else if(divisor>0)
             {
                dividend=dividend+divisor;//降低dividend(由于都是整数,降低之后肯定不溢出)
                count++; 
             }
         }



        if(dividend<0) dividend=-dividend;
        if(divisor<0) divisor=-divisor;//都转化为正的来处理

        unsigned int count_last=Caldeivide(dividend,divisor);
        if(count_last+count>INT_MAX&&sign)//同号的,最后结果是大于INT_MAX的需要进行异常处理 
            count=INT_MAX;//异常处理
        else //异号的,需要对结果是-2147483648的进行异常处理,但是前面声明的变量是unsigned int,所以不需要再处理了
            count=count_last+count;

        if(sign) return count;
        else return -count;
    }
private:
    int Caldeivide(int dividend,int divisor)//都是正的,无溢出的情况处理
    {
        int count=0;
        while(dividend>=divisor)
        {
            int count_1=1;
            int Sum=divisor;

            while(dividend>=Sum)
            {
                dividend=dividend-Sum;
                count=count_1+count;

                unsigned int sum1=Sum+Sum;
                if(sum1<=dividend && sum1<=INT_MAX)
                {
                    count_1=count_1+count_1;
                    Sum=sum1;//每次2倍速率增加
                }
                else
                    break;
            }

        }
       return count; 

    }


};


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;
        int res=0;
        int long dvd=labs(dividend);
        int long dvs=labs(divisor);

        while(dvd>=dvs)
        {
            long long temp=dvs,multiple=1;
            while(dvd>=(temp<<1))
            {
                temp=temp<<1;
                multiple<<=1;
            }
             dvd-=temp;
             res+=multiple;
        }


      return sign==1?res:-res;  
      return 0;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值