描述

不能使用乘法、除法和取模(mod)等运算,除开两个数得到结果,如果内存溢出则返回Integer类型的最大值。解释一下就是:输入两个数,第一个数是被除数dividend,第二个是除数divisor,要求是在不得使用乘法、除法和取模(mod)等运算的前提下,求出两个数的相除结果。

思路

有一个最简单直观的方法,设置一个i=1,比较dividend和divisor大小,如果满足dividend>divisor,就令divisor=divisor+divisor,i++,继续判断dividend>divisor,继续执行循环,直到不满足条件时候输出i的大小。

这种方法最简单直观,但是想想也直到,这个肯定在处理时间上超时。

那么还有什么方法类似于乘除法呢,想到了一种,移位。例如:现在定义一个数int i=2,那么如果执行i=i<<1,那么此时的i就等于4,相当于乘以二了。为了快速得到结果,我们可以加入移位运算,怎么用?用在哪?

现在我们提出一种方法,举个简单的例子:假设输入了两个数,被除数为13,除数为2,下面我们一步一步的解释这种方法:

1、让dividend=13,divisor=2。设一个全局变量的result=0,存储最终结果,设置一个临时结果为re=1,现在这个1表示divisor的值的大小,等于一个原始除数。

2、判断dividend是否大于divisor左移一位,即dividend > divisor<< 是否成立?成立则说明除数大小左移一位(即乘以2)也不会超过被除数,那么执行第3步,否则,执行第4步。

3、re=re<<,divisor=divisor<<,返回执行第2步。

4、判断当前被除数减去当前的除数是否大于等于原始的除数,即判断dividend-divisor>=2是否成立,成立,则说明还有再除以2的空间,只不过现在的除数已经变了,被除数的一部分也已经被除过了,那么就执行第5步,否则,执行第6步;如果不成立,执行第6步。

5、先把临时结果re的值加到最终结果result中去,然后让dividend=dividend-divisor,然后把divisor复位,即让divisor=2,重新执行第2步。

6、返回结果值result。

下面是每一步时,被除数dividend、除数divisor、中间结果re和最终结果result的状态:

步骤  dividend  divisor  re  result

1          13           2        1      0

2          13      2<<=4  1<<=2   0

3     13   4<<=8  2<<=4   0

4      13-8=5   复位为2    复位为1   re+result=4+0=4

5          5         2<<=4        1<<=2     4

6       5-4=1    复位为2 复位为1     re+result=2+4=6

然后就比较不了了,那么结果为6,bingo!

下面贴代码:

public static int divide(int dividend, int divisor) {
//特殊情况:当除数为0时,一定是内存溢出
if(divisor==0) return Integer.MAX_VALUE;
//判断符号位
int sign = 1;
if((dividend>0 && divisor<0) || (dividend<0 && divisor>0)) sign = -1;
//定义为长整型的目的是为了在取绝对值时不会内存溢出
//sor1作为局部的除数出现
long dend = Math.abs((long)dividend), sor = Math.abs((long)divisor), sor1=sor;
//特殊情况:当被除数为0或者被除数小于除数时,返回值一定是0
if(dividend==0 || dend<sor) return 0;
//把最终结果定义成全局变量
long result = 0;
while(true){
//定义一个中间结果,用于对全局结果的累加
long re = 1;
//如果当前的被除数还大于当前除数左移一位之后的数(即乘以2),那么进入循环
while(dend > sor1<<1){
//符合条件情况下,除数左移一位,中间结果也左移一位(中间结果的大小 等于 当前的sor1/sor的结果数)
re=re<<1;
sor1=sor1<<1;
}
result = result+re;
//此时说明中间除数已经到了一个临界点,即当前除数小于当前被除数,但左移一位就会大于被除数。
//判断dend与当前除数之间的差值是否大于等于原始除数,如果等于,说明还有除的空间,那么更新除数和被除数之后重返循环,否则结束
if((dend-sor1) >= sor){
dend=dend-sor1;
sor1=sor;
}else break;
}
//判断内存溢出
if(result*sign>Integer.MAX_VALUE || result*sign<Integer.MIN_VALUE) return Integer.MAX_VALUE;
return (int)result*sign;
}

  

     

Divide two integers without using multiplication, division and mod operator.的更多相关文章

  1. algorithm@ Divide two integers without using multiplication, division and mod operator. (Bit Operation)

    #include<bits/stdc++.h> using namespace std; int divide(int dividend, int divisor) { long long ...

  2. leetcode 29-> Divide Two Integers without using multiplication, division and mod operator

    class Solution(object): def divide(self, dividend, divisor): """ :type dividend: int ...

  3. [LeetCode] Divide Two Integers 两数相除

    Divide two integers without using multiplication, division and mod operator. If it is overflow, retu ...

  4. Leetcode Divide Two Integers

    Divide two integers without using multiplication, division and mod operator. 不用乘.除.求余操作,返回两整数相除的结果,结 ...

  5. leetcode-【中等题】Divide Two Integers

    题目 Divide two integers without using multiplication, division and mod operator. If it is overflow, r ...

  6. [LintCode] Divide Two Integers 两数相除

    Divide two integers without using multiplication, division and mod operator. If it is overflow, retu ...

  7. 62. Divide Two Integers

    Divide Two Integers Divide two integers without using multiplication, division and mod operator. 思路: ...

  8. Divide Two Integers leetcode

    题目:Divide Two Integers Divide two integers without using multiplication, division and mod operator. ...

  9. Java for LeetCode 029 Divide Two Integers

    Divide two integers without using multiplication, division and mod operator. If it is overflow, retu ...

随机推荐

  1. 用Python代码实现微信跳一跳作弊器

    最近随着微信版本的更新,在进入界面有个跳一跳的小游戏,在网上看到技术篇教你用Python来玩微信跳一跳 ( 转载自 " 工科给事中的技术博客 " ) 本文旨在总结,技术全靠大神完成 ...

  2. 前端优化:css雪碧图实践应用详解

    一 为什么需要使用雪碧图 二CSS雪碧图原理及应用 前端是接近用户体验的一个项目组成部分,合适的优化能够大大减少网页响应时间,合理的资源加载自然成为了工作中的要务,现在就结合实例讲解到底什么是css雪 ...

  3. Redis(八):Redis的复制(Master/Slave)

    Redis的复制(Master/Slave)目录导航: 是什么 能干嘛 怎么玩 复制原理 哨兵模式(sentinel) 复制的缺点 是什么 官网 行话:也就是我们所说的主从复制,主机数据更新后根据配置 ...

  4. CentOS7 LNMP+phpmyadmin环境搭建(三、安装phpmyadmin)

    之前我们已经安装了lnmp的环境,现在让我们来安装phpmyadmin. 跟前一样,yum默认的库里是没有phpmyadmin的,我们需要从epel库里进行安装,之前已经安装过epel的朋友就可以直接 ...

  5. master.HMaster: Failed to become active master

    Hbase集群启动后自动退出,日志错误: fatal error: master.HMaster: Failed to become active master java.io.IOException ...

  6. Dubbo client 启动报错:No provider available for the service use dubbo version 2.5.3

    1.异常 java.lang.IllegalStateException: Failed to check the status of the service org.ko.server.servic ...

  7. Hive操作之向分区表中导入数据的语义错误

    1.建完分区表之后,向表中导入数据 命令为: load data local inpath '/home/admin/Desktop/2015082818' into table db_web_dat ...

  8. 搭建Jupyter Notebook服务器

    昨天发了Jupyter的使用,补一篇Jupyter服务器的搭建~ 一.搭建Jupyter 1.安装 使用virtualenv建虚拟环境.在虚拟环境中安装jupyter.matplotlib等等需要的库 ...

  9. Python前戏

    1.Python解释器 官网:https://www.python.org/getit/ 因为Python的3.0和2.0版本有所差别,所以根据个人学习方向分别下载安装. 安装验证:打开命令提示符,执 ...

  10. 成都Uber优步司机奖励政策(1月20日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...