题目描述给定两个整数,被除数被除数divisor。两个数相除,不需要乘法、除法和模运算符。返回股息dividend除以divisor得到的商。整数除法的结果应截断(truncate)其小数部分,例如:truncate(8.345)=8andtruncate(-2.7335)=-2示例1:输入:dividend=10,divisor=3输出:3解释:10/3=truncate(3.33333..)=truncate(3)=3示例2:输入:dividend=7,divisor=-3输出:-2解释:7/-3=truncate(-2.33333..)=-2解题思路首先要考虑数的正负问题。如果除数和被除数都为正或负,则结果也为正,否则为负。用sign标记正负,然后把除数和被除数都转换成正数:intsign=1;if((dividend>0&&divisor<0)||(dividend<0&&divisor>0)){sign=-1;}int股息=Math.abs(股息);int除数=Math.abs(除数);要求不能用乘法、除法和求余运算来计算两个数相除的值,结果值四舍五入。说到运算,还得用到其他运算符,比如加法。例如,10/3转换为10并减去3,直到减去的数小于被除数。10-3=77-3=44-3=1<3上面已经减了3次,所以10/3=3,按照思路写出如下代码:publicintdivide(intdivide,intdivisor){符号=1;if((股息>0&&除数<0)||(股息<0&&除数>0)){sign=-1;}intdividends=Math.abs(dividend);int除数=Math.abs(除数);整数索引=0;while(dividends>=divisors){股息=股息-除数;索引++;}返回索引*符号;-2147483648,这是因为编码int占了四个字节,一个字节有八位。所以需要转换成long类型来避免数据越界问题:intsign=1;if((股息>0&&除数<0)||(股息<0&&除数>0)){sign=-1;}longdividends=Math.abs((long)dividend);长除数=Math.abs((长)除数);长指数=0;while(dividends>=divisors){股息=股息-除数;索引++;}if(index>Integer.MAX_VALUE&&sign==1){returnInteger.MAX_VALUE*sign;}return(int)索引*符号;结果:结果超时,因为需要重复次数,时间复杂度为O(n)。这里需要用到递减法,比如10/1=1010-1=9index=19-1=8index=28-1=7index=37-1=6index=46-1=5index=5....1-1=0index=10这是十步操作,需要做的递进操作,红利加倍。例如,上面可以转化为:10-1=9index=1=19-1*2=7index=1+1*2=37-1*2*2=3index=1+1*2+1*2*2=7然后匹配3-1*2*2*2<0,需要进行上面的减法运算3-1=2index=7+1=82-1*2=0index=7+1+1*2=10具体过程:根据以上思路,可以得到如下代码:intsign=1;if((股息>0&&除数<0)||(股息<0&&除数>0)){sign=-1;}longdividends=Math.abs((long)dividend);长除数=Math.abs((长)除数);长指数=0;while(dividends>=divisors){longtemp=divisors;长我=1;while(dividends>=temp){股息=dividends-temp;索引=索引+我;温度=te熔点<<1;我=我<<1;}}if(index>Integer.MAX_VALUE&&sign==1){returnInteger.MAX_VALUE*sign;}return(int)索引*符号;将除法转为减法,逐个累加减法需要考虑int范围溢出问题。这里统一改成long型累加归约所需的时间负复杂度为O(n),很容易超时。这里,需要转化为递增减法,即每次都将被减数翻倍。如果您觉得文章对您有帮助,请点个赞吧!
