LeetCode第二十九题(两数相除)

128 阅读2分钟

倍乘法

核心思想: 为了防止结果溢出,被除数和除数均转为负数。让除数依次倍乘(加法实现),直至被除数减去大于被除数的除数的最小倍乘的结果大于除数的最小倍乘,得到商的取值范围(或确定值),若是取值范围,则让被除数减去大于被除数的除数的最小倍乘,结果与除数按相同规则继续进行,直至被除数大于除数,每趟循环的相除结果之和即两数相除的最终结果(商)

举例说明: 60/8 = -60/-8 = (-60-(-32))/-8 + 4 = (-60-(-32)-(-16))/-8 + 2 + 4 = (-60-(-32)-(-16)-(-8))/-8 + 1 + 2 + 4 = 7

注意: 被除数和除数均为32位有符号整数,当被除数为32位有符号整数的最小值且除数为-1时,结果为32位有符号整数的最大值+1,故取32位有符号整数的最大值。

class Solution {
    public int divide(int dividend, int divisor) {
        if(dividend == Integer.MIN_VALUE && divisor == -1)//特判
            return Integer.MAX_VALUE;
        int res = 0;//相除结果(商)的绝对值
        boolean flag = false;//相除结果(商)的符号
        if((dividend < 0 && divisor < 0) || (dividend > 0 && divisor > 0))//被除数和除数的符号相同,相除结果的符号为正号
            flag = true;
        //被除数和除数均转为负数,防止结果溢出
        dividend = dividend > 0 ? -dividend : dividend;
        divisor = divisor > 0 ? -divisor : divisor;
        while(dividend <= divisor){//直至被除数大于除数
            int count = 1;//当前循环的相除结果
            int divisorMulti = divisor;//除数的倍乘
            while(dividend - divisorMulti <= divisorMulti){//直至被除数减去大于被除数的除数的最小倍乘的结果大于除数的最小倍乘
                divisorMulti += divisorMulti;//除数依次倍乘(由于除数转为负数,倍乘的结果越来越小,得到大于被除数的除数的最小倍乘)
                count += count;//当前循环的相除结果相应倍乘
            }
            dividend -= divisorMulti;//被除数减去大于被除数的除数的最小倍乘
            res += count;//每趟循环的相除结果之和
        }
        if(flag)
            return res;
        else
            return -res;
    }
}