栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

两数相除,不用除法-java

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

两数相除,不用除法-java

最初的想法:
//a不停减去b,减到a小于b,计算减了多少次,就是结果
    public int divide(int a,int b){
        int sign=1;
        //如果a或b有一个是负数,那么就定义最后的结果为负数
        if((a>0&&b<0)||(a<0&&b>0)){
            sign = -1;
        }
        //Math.abs(-2147483648)=-2147483648
        a = Math.abs(a);
        b = Math.abs(b);
        int res = 0;
        while(a>=b){
            a-=b;
            res++;
        }
        return sign*res;
    }
考虑边界问题
    public int divide(int a,int b){
        //环境只支持32位整数
        // 32 位最大值:2^31 - 1 = 2147483647
        // 32 位最小值:-2^31 = -2147483648
        // -2147483648 / (-1) = 2147483648 > 2147483647 越界了
        if(a==Integer.MIN_VALUE && b==-1)
            return Integer.MAX_VALUE;
        //如果a或b有一个是负数,那么就定义最后的结果为负数
        //用异或^来判断a和b符号是否相同,都为正数或都为负数异或的结果就是false,一个为正一个为负就是true
        int sign = (a>0)^(b>0)?-1:1;
        if(a>0) a = -a;
        if(b>0) b = -b;
        int res = 0;
        while(a<=b){
            a -= b;
            res ++;
        }
        return sign*res;
    }
优化,考虑减去除数的倍数
// 时间复杂度:O(logn * logn),n 是最大值 2147483647 --> 10^10
public int divide(int a, int b) {
    if (a == Integer.MIN_VALUE && b == -1)
        return Integer.MAX_VALUE;
    int sign = (a > 0) ^ (b > 0) ? -1 : 1;
    if (a > 0) a = -a;
    if (b > 0) b = -b;
    int res = 0;
    while (a <= b) {
        int value = b;
        int k = 1;
        // 0xc0000000 是十进制 -2^30 的十六进制的表示
        // 判断 value >= 0xc0000000 的原因:保证 value + value 不会溢出
        // 可以这样判断的原因是:0xc0000000 是最小值 -2^31 的一半,
        // 而 a 的值不可能比 -2^31 还要小,所以 value 不可能比 0xc0000000 小
        // -2^31 / 2 = -2^30
        while (value >= 0xc0000000 && a <= value + value) {
            value += value;
            // 代码优化:如果 k 已经大于最大值的一半的话,那么直接返回最小值
            // 因为这个时候 k += k 的话肯定会大于等于 2147483648 ,这个超过了题目给的范围
            if (k > Integer.MAX_VALUE / 2) {
                return Integer.MIN_VALUE;
            }
            k += k;
        }
        a -= value;
        res += k;
    }
    // bug 修复:因为不能使用乘号,所以将乘号换成三目运算符
    return sign == 1 ? res : -res;
}
// 时间复杂度:O(1)
public int divide(int a, int b) {
    if (a == Integer.MIN_VALUE && b == -1)
        return Integer.MAX_VALUE;
    int sign = (a > 0) ^ (b > 0) ? -1 : 1;
    a = Math.abs(a);
    b = Math.abs(b);
    int res = 0;
    for (int i = 31; i >= 0; i--) {
        // 首先,右移的话,再怎么着也不会越界
        // 其次,无符号右移的目的是:将 -2147483648 看成 2147483648
        // 注意,这里不能是 (a >>> i) >= b 而应该是 (a >>> i) - b >= 0
        // 这个也是为了避免 b = -2147483648,如果 b = -2147483648
        // 那么 (a >>> i) >= b 永远为 true,但是 (a >>> i) - b >= 0 为 false
        if ((a >>> i) - b >= 0) { // a >= (b << i)
            a -= (b << i);
            // 代码优化:这里控制 res 大于等于 INT_MAX
            if (res > Integer.MAX_VALUE - (1 << i)) {
                return Integer.MIN_VALUE;
            }
            res += (1 << i);
        }
    }
    // bug 修复:因为不能使用乘号,所以将乘号换成三目运算符
    return sign == 1 ? res : -res;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/782246.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号