leetcode算法整理29两数相除

LEETCODE注解
29:两数相除
给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。

返回被除数 dividend 除以除数 divisor 得到的商。
说明:

被除数和除数均为 32 位有符号整数。
除数不为 0。
假设我们的环境只能存储 32 位有符号整数,其数值范围是int [min,  max]。
本题中,如果除法结果溢出,则返回 int最大值

解法一:最容易想到的是做减法。
减法容易遇到的问题:
1.除数与被除数符号问题,会有四种情况(++,±,-+,–)比较麻烦。解决方法将除数与被除数都转化成负数或正数。
转化正数出现的问题:dividend=int类型最小值时,转化成正数会溢出问题。因此,决定dividend与divisor都转化成负数。
2.结果溢出问题。只存在dividend=Integer.MIN_VALUE && divisor=-1这一种情况。因此单独处理。
代码如下:

class Solution {
    public int divide(int dividend, int divisor) {
    if(dividend==Integer.MIN_VALUE && divisor==-1)   return Integer.MAX_VALUE;
    int x = dividend ;
    int y = divisor ;
    if(x > 0) x = -x;
    if(y > 0 ) y = -y;
    if(x > y) return 0;
    int flag = 0;
    if(dividend>0&&divisor<0 || dividend<0&&divisor>0) flag = 1;
    int count = 0;
    while(x <= y) 
    {
        x = x - y;
        count++;
    }
    if(flag==0) return count;
    else return -count;
    }
}

但显而易见这种方法的最大问题速度太慢,超出时间限制。因此需要第二种解法。
解法二:既然一个一个减去太慢,那让减得越来越多。
例如:
15 2 0
13 4 0+1=1
9 8 0+1+2=3
1 16 0+1+2+4=7
1 2 算出结果
代码如下

class Solution {
    public int divide(int dividend, int divisor) {
    if(dividend==Integer.MIN_VALUE && divisor==-1)   return Integer.MAX_VALUE;
    int x = dividend ;
    int y = divisor ;
    if(x > 0) x = -x;
    if(y > 0 ) y = -y;
    int disy = y;
    if(x > y) return 0;
    int flag = 0;
    if(dividend>0&&divisor<0 || dividend<0&&divisor>0) flag = 1;
    int count = 0;
    int multiple = 1;
    while(x <= disy) 
    {
        if(x-y<=0)
        {
            x = x - y;
            y += y;//翻倍减少
            count += multiple;
            multiple += multiple;//翻倍增加
        }
        else//y重新归到初始值
        {
            y = disy;
            multiple = 1;
        }
    }
    if(flag==0) return count;
    else return -count;
    }
}

正如代码所示,每过一轮,y翻倍,multiple翻倍增加。等价于2的n次方*y的速度减少。直到剩余x小于当前y时,y值重新回到初始值divisor。重新进行循环。

发布了5 篇原创文章 · 获赞 1 · 访问量 78

猜你喜欢

转载自blog.csdn.net/qq_39502383/article/details/104061888
今日推荐