Divide two integers without using multiplication, division and mod operator.
思路:先想到的是做减法,但是效率在两数差距大的时候复杂度很高,
之后想到移位的方式,把除数和余数提高,复杂度较低。
例如 19 除以 3 , 记录两个值 除数 3 商1 , 移位一次 除数6 商 2 ,再移位 除数 12 商 4 ,达到19的一半,
ret=0 ; ret += 4; 19 -12 = 7 被除数为7 , 再把 12 和 4 右移 一次比对, 直到 商为1时 再比对一次。
看了一下测试数据,发现十分蛋疼,做了很多优化,除数为+- 1 ,被除数为0, 除数为+-2 的情况。
例外 除数右移的时候不可越界,所以要和19的一半比较,若较小,再移位。
另外本是讲 两数都变成正数计算,可是INT_MIN 变成正数还是越界了,直接用longlong 吧,好恶心啊。
整不了算法,净是些细枝末节的东西,吐血。
混乱代码如下
class Solution {
public:
int help(long long dividend,long long divisor)
{
if(dividend ==0)
return 0;
//符号转换
int sign = 0;
if( dividend < 0 && divisor >0 )
{
sign = -1;
dividend = 0 - dividend;
}
if( dividend >0 && divisor <0 )
{
sign = -1;
divisor = 0 - divisor;
}
if (dividend <0&& divisor <0 )
{
divisor = 0 - divisor;
dividend = 0 - dividend;
}
if(dividend < divisor)
return 0;
int ret = 0 ;
if(divisor==1)
{
ret = dividend;
if(sign == -1)
ret = 0 - ret;
return ret;
}
if(divisor==2)
{
ret = dividend >>1;
if(sign == -1)
ret = 0 - ret;
return ret;
}
long long tmp = 1;
long long half = dividend >>1;
//find the first bit
while( half > divisor) {
divisor = divisor<<1;
tmp = tmp << 1;
if( half < divisor ){
ret += tmp;
dividend -= divisor;
if(dividend ==0)
{
if(sign == -1)
ret = 0 - ret;
return ret;
}
}
}
while(tmp>1) {
if(dividend < divisor ) {
tmp = tmp >>1;
divisor = divisor >>1;
}else{
ret += tmp;
dividend -= divisor;
if(dividend ==0)
{
if(sign == -1)
ret = 0 - ret;
return ret;
}
}
}
if(divisor <= dividend)
ret++;
if(sign == -1)
ret = 0 - ret;
return ret;
}
int divide(int dividend, int divisor) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
long long a = dividend ;
long long b = divisor;
return help(a,b);
}
};