LeetCode:Divide Two Integers

26 篇文章 0 订阅
8 篇文章 0 订阅
/**
Divide two integers without using multiplication, division and mod operator.

题目大意:算两个整数相除的结果,不能用乘号、除号、求余号
注意:提供的两个数只限制是整数,可以是正、负、零
**/

public class Solution {
    public int divide(int dividend, int divisor) {
        //return solve1(dividend, divisor);   //违反题意
        //return solve2(dividend, divisor);   //超时,且不能处理极端数值
        return solve3(dividend, divisor);
    }
    
    //========================== solve1 =============================
    //我偏要直接用除号,来咬我啊~
    //想不到居然也Accept了...
    private int solve1(int dividend, int divisor){
        return dividend / divisor;
    }
    
    //========================== solve2 =============================
    //既然不能用除号,那就用减号吧
    //连乘号都不能用,那就用减号来解决符号问题
    //如果出现被除数很大,除数很小,那是一定会超时
    //超时之外,这个解法更大的错误在于:当输入最小的那个负数,会导致失败!(最大整数的比最小负数的绝对值要小)
    private int solve2(int dividend, int divisor){
        int result = 0;
        
        //记住最后的符号
        int mult = -1;
        if((dividend>=0 && divisor>=0)
                || (dividend<0 && divisor<0))
            mult = 1;
        
        //全部变成正的
        //在这里,如果输入的是-2147483648,那就肯定会出错,因为对于int来说,这个数字是没有正数的
        if(dividend < 0)
            dividend = 0 - dividend;
        if(divisor < 0)
            divisor = 0 - divisor;

        //用减号求商
        while(dividend >= divisor){
            dividend -= divisor;
            result++;
        }
        
        //确定符号
        if(mult == -1)
            result = 0 - result;
        
        return result;
    }
    
    //========================== solve3 =============================
    //其实这里采取的也是除数一点点往上加,看什么时候能加到最接近被除数的时候,答案就出来了
    //只不过先从最大可能的那个数开始加,减少加的次数,降低操作次数
    //这类题重点在于,从一开始就必须要进行类型转换,变成long,否则对于极端数值没法操作
    private int solve3(int dividend, int divisor){
        //一开始就转换成long
        long div1 = (long)dividend;
        long div2 = (long)divisor;
        
        //记住最后的符号
        int mult = -1;
        if((div1>=0 && div2>=0)
                || (div1<0 && div2<0))
            mult = 1;
            
        //全部变成正的
        if(div1 < 0)
            div1 = 0 - div1;
        if(div2 < 0)
            div2 = 0 - div2;    
        
        //存放被除数的倍数的数组,由于是int,最多不可能超过2^32    
        long[] numbers = new long[33];
        //存放倍数本身
        long[] times = new long[33];
        long time = 1L;
        int num = 0;
        
        //存入当前除数,作为单倍体
        numbers[num] = div2;
        times[num] = time;
        num++;
        
        //将除数的各种2的倍数存好,直到超过被除数
        while(div2 <= div1){
            div2 = div2 + div2;
            time = time + time;
            
            if(div2 <= div1){
                numbers[num] = div2;
                times[num] = time;
                num++;
            }
        }
        
        //用存储好的数加起来,看加多少可以加到被除数
        long sumUp = 0L;
        long timeUp = 0L;
        for(int i=num-1; i>=0; i--){
            //这种是可以整除的情况
            if(sumUp == div1)
                break;
            
            //从除数的最大可能倍数一直到除数本身
            //最大限度的缩减需要加的次数
            while(sumUp+numbers[i] <= div1){    //注意这里的等号,是必须要的
                sumUp += numbers[i];
                timeUp += times[i];
            }
        }
        
        if(mult == -1)
            timeUp = 0 - timeUp;
            
        return (int)timeUp;
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值