leetcode29 两数相除

 

思路:

1.负数转化为正数符合我们的习惯,但是有效区间为[−2^31,  2^31 − 1],显然−2^31,转化为正数会溢出。那么只能全部转化为负数来做了。

2.直接减肯定会超时,不然这题没意义了。其实这一题就是看dividend 最多可以分解为多少个divisor 。

我们先假设dividend >0且divisor >0。

因为无法用乘法,我们可以用位运算,每次左移n位,则相当于divisor *(2^n)了。我们试探性的累加n,直到不能加为止。

int n = 0;//这一次左移几位,初始为0
int res = 0;//结果
while(dividend >= (divisor<<n)){
    // 减去了2^n个
    dividend -= divisor<<n;
    // 1<<n == 2^n
    res += 1<<n;
    n++;
}

当然,这样累加中间肯定会漏掉许多,所以当循环退出后,我们应该继续做同样的事情,写个递归就ok。

下面是完整代码:

说明: divisor<<n < 0 这个是因为我觉得负数溢出时,会变正数,未仔细想,反正就是个环嘛。

class Solution {
    public int divide(int dividend, int divisor) {
        int reverse = 0;
        if(dividend > 0) {
            dividend = 0-dividend;
            reverse++;
        }
        if(divisor > 0) {
            divisor = 0-divisor;
            reverse++;
        }


        int res = dfs(dividend,divisor);

        // 处理结果
        if(reverse == 1) {
            return res;
        }else {
            // 反转可能会溢出
            if(res == Integer.MIN_VALUE) {
                return Integer.MAX_VALUE;
            }
            return 0-res;
        }
    }

    private int dfs(int dividend, int divisor) {
        if(dividend > divisor){
            return 0;
        }
        int res = 0;
        int n = 0;
        while(divisor<<n < 0 && dividend <= divisor<<n){
            // 减去了2^n个
            dividend -= divisor<<n;
            // 2^n
            res -= 1<<n;
            // 退出条件
            if(dividend == 0) {
                return res;
            }
            n++;
        }
        return res + dfs(dividend,divisor);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值