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。重新进行循环。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值