[LeetCode] 29. 两数相除(java实现)二进制优化

1. 题目

在这里插入图片描述
在这里插入图片描述

2. 读题(需要重点注意的东西)

思路(二进制优化):
主要思路是用减法减出最后所需要的商,但是一个个减是肯定会超时的,那么怎么优化呢?


二进制优化:
可以考虑使用二进制的方式来减,这就将所需减次数从n次缩小到了logn次:
设被除数为x,除数为y,则可以预处理出2^30^y、2^29^y、2^28^y、...、2^0^y的值,然后从大到小去看每一项,即如果被除数x大于230y,则使得x = x - 230y,依次类推 229y、228y、…、20y,即可反推出商。


接下来给个例子辅助理解:
设有被除数为十进制数50,除数为9,预处理出22 * 9 = 36 , 21 * 9 = 18, 20 * 9 = 9
则有:
50 - 22 * 9 = 50 - 36 = 14
14 - 20 * 9 = 5
得到余数为5,商为22 + 20 = 5


代码实现步骤:

  1. 处理符号,如果x和y的符号不同,需要全部处理为正数,若符号不同,最后则需要在答案中加上一个负号。(注意,最小负数的绝对值比最大正数多1,因此最小的负数转为正数后可能会溢出,因此要用longlong来存储转换后的值
  2. 计算 230y、229y、228y、…、20y的值
  3. 特判,若答案溢出,则返回 Integer.MAX_VALUE

3. 解法

---------------------------------------------------解法---------------------------------------------------

class Solution {
    public int divide(int x, int y) {
    	// 特判
        if(x == -2147483648 && y == 1) return Integer.MIN_VALUE;
        // 处理符号
        int flag = 1;
        if(x > 0 && y < 0 || x < 0 && y > 0) flag = -1;
        long a = x,b = y;
        if(a < 0) a = -a;
        if(b < 0) b = -b;
        // 预处理出2的各个次方乘y的结果
        long[] exp = new long[31];
        for(int i = 0;i < 31;i++) exp[i] = (1 << i) * b;
        
        // 减出商
        long res = 0;
        for(int i = 30;i >= 0;i--){
            if(a - exp[i] >= 0){
                a -= exp[i];
                res += (long)1 << i;
            }
        }
        res = flag*res;
        if(res > Integer.MAX_VALUE || res < Integer.MIN_VALUE) return Integer.MAX_VALUE;
        return (int)res;
    }
}

4. 可能有帮助的前置习题

5. 所用到的数据结构与算法思想

  • 二进制优化

6. 总结

用二进制优化来使得时间复杂度优化为logn级,注意边界条件

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cloudeeeee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值