Leetcode 29. Divide Two Integers

一道有意思的题目,难度不是很大,但是不仅思路多,而且写法也非常多,真是有趣。

第一想法,这不就是大数除法吗,觉得特别麻烦。
第二想法,发现这并不是大数,于是就有一些有趣的想法了。

第一种解法

ab=eIn(a)eIn(b)=eIn(a)In(b)

class Solution {
    public:
        int divide(int dividend, int divisor) {
            /** a/b = e^(ln(a))/e^(ln(b)) = e^(ln(a)-ln(b)) **/
            if(dividend==0)  return 0;
            if(divisor==0)  return INT_MAX;

            double t1=log(fabs(dividend));
            double t2=log(fabs(divisor));
            long long result=double(exp(t1-t2));
            if((dividend<0) ^ (divisor<0))  result=-result;
            if(result>INT_MAX)  result=INT_MAX;
            return result;
        }
    };

第二种解法

模拟二进制计算,总结一下规律。
在计算机内一个正整数

ret=a0+a12+a222+......+a29229+a30230+a31231ai=0 or 1

所以 BA 可以表示为
ret=BAA×(a0+a12+a222+......+a29229+a30230+a31231)=B

  1. 我们可以发现,左右两边同时向右移31位可得A*a_{31} = B>>31
    于是可以得到if (B>>31) > A, then a31 = 1; else a31 = 0

  2. 左右两边同时向右移30位可得A*a30 + A*a30*2 = B>>30,也就是说a30 = ((B>>30) -a30*A*2)/A,右式也可以写成(B-a31*A<<31)>>30,所以我们设置一个变量B' = B - a31*A<<31
    于是可以得到if (B'>>30) > A, then a30 = 1; else a30 = 0

  3. 左右两边同时向右移29位得到a29 = ((B-a31*A<<31-a30*A<<30)>>29)/A,我们设置变量B'' = B' - a30*A<<30 .
    可得if (B''>>29) > A, then a29 = 1; else a29 = 0;

然后以此类推。

class Solution(object):
    def divide(self, dividend, divisor):
        """
        :type dividend: int
        :type divisor: int
        :rtype: int 
        """
        flag = (dividend > 0) ^ (divisor > 0)
        dividend, divisor = abs(dividend), abs(divisor)
        ans = 0
        for i in range(31, -1, -1):
            if (dividend>>i) >= divisor:
                ans <<= 1
                ans |= 1
                dividend -= (divisor << i)
            else:
                ans <<= 1
        if flag:
            ans = -ans
        return min(max(-2147483648, ans), 2147483647)

这种方法应该还有一种类似的写法
证明应该是类似的,都是模拟二进制计算

class Solution:
    # @return an integer
    def divide(self, dividend, divisor):
        positive = (dividend < 0) is (divisor < 0)
        dividend, divisor = abs(dividend), abs(divisor)
        res = 0
        while dividend >= divisor:
            temp, i = divisor, 1
            while dividend >= temp:
                dividend -= temp
                res += i
                i <<= 1
                temp <<= 1
        if not positive:
            res = -res
        return min(max(-2147483648, res), 2147483647)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值