算法训练-整数除法

整数除法

题目描述

给定两个整数 ab ,求它们的除法的商 a/b ,要求不得使用乘号 ‘*’、除号 ‘/’ 以及求余符号 ‘%’ 。

示例1:

输入:a = 15, b = 2
输出:7
解释:15/2 = truncate(7.5) = 7

示例2:

输入:a = 7, b = -3
输出:0
解释:7/-3 = truncate(-2.33333..) = -2

示例3:

输入:a = 0, b = 1
输出:0

示例4:

输入:a = 1, b = 1
输出:1

提示:-231<=a,b<=231-1,b!=0

题目来源:

剑指offer(专项突击版) [剑指offer|| 001]整数除法

https://leetcode-cn.com/problems/divide-two-integers/

题解

设sum为a除以b的商,a和b的范围是-2^31 到2^31-1,如果按照{a=a-b,sum++},当且仅当a>=b的思路时间复杂度太高,肯定会超时,所以我们应该时循环的次数变得尽可能的少。

我们可以让b1=b,task=1,累加(b1+b1),直到b1+b1>a,此时的b已经是a的最大可除数,记录b1累加的次数task,此时b1=task*b,再将a-b1,可以将a拆分成更小的数,将task重置为1,b1=b,继续执行上述操作,最终可以求出a除以b的商

设test =b,task=1,sum=0,重复执行此操作:b每次累加(b=b+b),task也累加(task=task+task),a=a-test,sum=sum+task,直到a<=test+test,操作结束.再对a和b的大小进行判断,如果此时a<b,则返回sum,如果a=b,返回sum+1

上述关系可以表示成:(a-task1×b-task2×b-…taskn×b)/b+task1+task2+…taskn

例如:a=60,b=13,a/b=(60-52)/13+4,sum=4.a=70,b=12,a/b=(70-48-12)/12+4+1

var divide = function(a, b) {
    let num = a
    let sum = 0
    if(a>=0&&b>0){
        if(a>=Math.pow(2,31)-1&&b==1){
            return Math.pow(2,31)-1
        }
        for(let i=1;i;i++){
            let test = b
            let task = 1
            if(a<b){
                return sum
            }
            if(a==b){
                return sum+1
            }
            while(a>test+test){
                test+=test
                task+=task
            }
            a-=test
            sum+=task
            }
    }else if(a<=0&&b<0){
        if(a<=-Math.pow(2,31)&&b==-1){
            return Math.pow(2,31)-1
        }
        for(let i=1;i;i++){
            let test = -b
            let task = 1
            if(-a<-b){
                return sum
            }
            if(a==b){
                return sum+1
            }
            while(-a>test+test){
                test+=test
                task+=task
            }
            a+=test
            sum+=task
        }
    }else if(a>=0&&b<0){
        if(a>=Math.pow(2,31)-1&&b==-1){
            return Math.pow(2,31)-1
        }
        for(let i=1;i;i++){
            let test = b
            let task = 1
            if(a<-b){
                return -sum
            }
            if(a==-b){
                return -sum-1
            }
            while(a>Math.abs(test+test)){
                test+=test
                task+=task
            }
            a+=test
            sum+=task
        }
    }else if(a<=0&&b>0){
        if(a<-Math.pow(2,31)&&b==1){
            return Math.pow(2,31)-1
        }
        for(let i=1;i;i++){
            let test = b
            let task = 1

            if(-a<b){
                return -sum
            }
            if(-a==b){
                return -sum-1
            }
            while(-a>test+test){
                test+=test
                task+=task
            }
            a+=test
            sum+=task
        }
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值