剑指 Offer II 001. 整数除法

题干

``

public class Test1 {
    /**
     * @param a 被除数
     * @param b 除数
     * @return result 结果
     * <p>
     * ops: ① 除数不能为0
     * ② 整数范围 - 2^31 到  2^31 -1
     * ③ 注意正负号 为了判断先将正负号统一为负号
     * <p>
     * sol: 将除数不断扩大为原来的二倍,避免重复+1复杂度过高
     *      若除数二倍大于被除数时 被除数减去除数 ,继续将减完的数当作被除数 此时返回结果从 0 变为上一次乘的倍数
     * 例 13/3 num=1
     * 13>6 num=2
     * 13>12 num=4
     * 13<24 num = 8 所以result += num;
     * 被除数 13-12 =1(做减法之后会判断减去之后被除数是否还大于除数
     * 1 < 2 ;
     * 此时被除数a = 1小于b = 2 所以直接返回 result
     *
     */
    public static int divide(int a, int b) {
        //判断特殊情况
        if (a == Integer.MIN_VALUE && b == -1) {
            return Integer.MAX_VALUE;
        }
        if (b == 0) {
            return 0;
        }

        //结果
        int result = 0;
        //增大的倍数
        int num = 1;
        //标志位 flag = 0 结果为负数,1为正数
        int flag;
        //a^b为二进制数取异或,>>>符号为无符号移位,移31位后只剩下符号位
        if (((a ^ b) >>> 31) == 0) {
            flag = 1;
        } else {
            flag = 0;
        }
        //将正负号统一划位负 因为在下面算法除数不断乘2,不能让其二倍的模大于2^31
        if (a > 0) {
            a = -a;
        }
        if (b > 0) {
            b = -b;
        }
        //判断特殊情况
        if (a > b) {
            return 0;
        }
        //算法开始
        if (b == -1) {
            return flag == 1 ? -a : a;
        } else {
            //进入循环 每次a-b,若2 * 除数 <= 被除数,则 b = b * 2 判断a是否大于b,当a<b的时候退出循环
            while (a <= b) {
                int value = b;
                while (a < value + value) {
                    //VALUE 不能小于Integer_Min/2
                    if (value < -1073741824) {
                        break;
                    }
                    num = num * 2;
                    value += value;
                }
                result = result + num;
                a = a - value;
                num = 1;
            }

            return flag == 1 ? result : -1 * result;
        }
    }

 

posted @ 2022-01-18 23:14  Clectronic  阅读(52)  评论(0)    收藏  举报