Leetcode 29 - Divide Two Integers(二进制分解)

题意

在不使用%*/的情况下, 求int x / int y

思路

算法1

假设 x/y=z 。最先想的是二分一下z的多少,但是我们考虑到在judge的时候,不能使用乘法,于是这个想法基本可以排除。

我们想一下在小学的时候算除法的过程:即用被除数一直去减除数直到不够减。那么我们能否考虑:假设我们这次减1个,下次减2个,下次减4个呢,即我们将每次减的数翻倍。其实就是一个二进制分解的过程。

现在,假设我们要计算 37/4=9 。我们这样想,即 37=49+1 。我们将9进行二进制表示为1001。即 37=4(23+20)+1

其实就是用 37423 ,再减去 420 。即每次找到够减的那个4的 2k 倍。

显然,我们不能从最低的 20 开始减,于是,我们必须先要计算出来最大的并且够减的那个 2k 。然后每次将y向右移动1位,去判断下一个是否够减,不够减的话继续移动。直到最后 x<y 即可。

算法2

其实可以二分一下z是多少,然后judge的时候利用快速加,原理同快速幂。时间复杂度为loglog

细节

用INT_MIN / -1的结果会溢出,应该处理。

代码

//algorithm1
#define LL long long

class Solution {
public:
    int divide(int x, int y) {
        if (y == 0) return INT_MAX;
        LL nx = abs((LL)x), ny = abs((LL)y);
        LL sum = 0, p = 1;
        while (ny <= nx) ny <<= 1, p <<= 1;
        while (nx >= abs((LL)y)) {
            while (ny > nx) ny >>= 1, p >>= 1;
            sum += p; nx -= ny;
            ny >>= 1; p >>= 1;
        }
        sum = ((x > 0 && y > 0) || (x < 0 && y < 0)) ? sum : -sum;
        return sum > INT_MAX ? INT_MAX : sum;
    }
};

//algorithm2
#define LL long long

class Solution {
public:

    LL quickAdd(LL x, LL n) {
        if (n == 1) return x;
        if (n == 0) return 0;
        LL t = quickAdd(x, n >> 1);
        if (n & 1) return t + t + x;
        return t + t;
    }

    int divide(int x, int y) {
        if (y == 0) return INT_MAX;
        LL nx = abs((LL)x), ny = abs((LL)y);
        LL l = 0, r = nx, m, ans = 0;
        while (l <= r) {
            m = l + (r - l >> 1);
            if (nx - quickAdd(ny, m) >= ny) l = m + 1;
            else r = m - 1, ans = m;
        }
        ans = ((x < 0 && y < 0) || (x > 0 && y > 0)) ? ans : -ans;
        return ans > INT_MAX ? INT_MAX : ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值