LeetCode 29. Divide Two Integers

题目:

给定两个整数的被除数和除数,在不使用乘法、除法和余运算符的情况下对两个整数进行除法;返回商;向零截断。

被除数和除数都是32位带符号整数;除数永远不会是0

假设我们处理的环境只能存储32位带符号整数范围内的整数:[- 2^31,2^31 - 1]。对于这个问题,假设函数在除法结果溢出时返回2^31 - 1。

Given two integers dividend and divisor, divide two integers without using multiplication, division and mod operator.

Return the quotient after dividing dividend by divisor.

The integer division should truncate toward zero.

Input: dividend = 10, divisor = 3      Output: 3
Input: dividend = 7, divisor = -3      Output: -2

Note:
  Both dividend and divisor will be 32-bit signed integers.
  The divisor will never be 0.
  Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−231,  231 − 1]. For the purpose of this problem, assume that your function returns 231 − 1 when the division result overflows.

 

参考:

 https://blog.csdn.net/makuiyu/article/details/43417749 

 

思路:

(更具体的思路可见参考)

【当N和m都为正数时】

被除数N 除数m

由于每个数都可以表示为: 

试着将被除数表示为:(a1,a2,……,an不一定是1、2、3……)

因此N可以表示为m的倍数:

因此,用count记录当前倍数,每次找出当前最小的使下式成立的ai,

   

令:

且:

其中2的次方可用位运算实现

最后当newN < m时,停止运算,此时的count为所要求的倍数

 

【注意】

符号方面:上面的算法为当N和m都为正数时,因此需要额外记录符号,再将N和m都转化为其自己的绝对值

边界方面:

为了防止溢出,使用long来进行计算,但是返回值需要是int类型,因此在转换时需要判断是否超出正负边界,超出则输出边界值

 

代码:

class Solution {
    public int divide(int dividend, int divisor) {
        if(dividend==0) {
            return 0;
        }

        long count = 0;
        long i = 1;
        
        // 1正 -1负
        int flag = ((dividend>0 && divisor>0)||(dividend<0 && divisor<0))?1:-1;
    	
        long l_dividend = Math.abs((long)dividend);
        long l_divisor = Math.abs((long)divisor);
    	
        // 寻找倍数
        while(l_dividend >= l_divisor) {
            while(l_dividend >= l_divisor * i ) {
                i = i<<1;
            }

            i = i>>1;
            count = count + i;
            l_dividend = l_dividend - l_divisor * i;
            i=1;
        }
    	
        // 边界处理
        int MAX_ = 2147483647;
        int MIN_ = -2147483648;
    	
        if(flag<0) {
            count = -count;
            if(count<MIN_) {
                return MIN_;
            }
        }else {
            if(count>MAX_) {
                return MAX_;
            }
        }
    	
        return (int)count;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值