您的位置:首页 > 其它

LeetCode Divide Two Integers

2013-12-13 10:25 423 查看
以前听过这题,也思考过,但到自己做时问题才暴漏出来,最终还是提交别人的通过的,哎,后悔呀,在思考一点是不是我也可以想到呢(我有无数次这样的悔恨,放弃太早了)?

下面的是我的方法,也是用了移位运算,时间复杂度也是lg(n)还是没通过,可见leetCode这道题还是挺严的,思路是这样的:先判断结果集所在的区间,然后二分查找,直到找到结果。如下:

int divide(int dividend, int divisor) {
if(divisor==0)
return -1;
if (dividend==0)
return 0;
if (divisor==1)
{
return dividend;
}
if (divisor==2)
{
return dividend>>1;
}

int signal=1;
if (dividend>0&&divisor<0||dividend<0&&divisor>0)
{
signal = -1;
}
if(dividend<0)
dividend = -dividend;
if(divisor<0)
divisor = -divisor;

if (divisor>dividend)
{
return 0;
}
else
{
int j=1,i=1;
int step=1;
int start,end=divisor;
while(end<dividend)
{
end<<=1;
j<<=1;
}
if (end==dividend)
{
if (signal<0)
return -j;
else
return j;
}
start = end>>1;
i = j>>1;
int mid,k;
while(start<end)
{
mid = (start+end)>>1;
k = (i+j)>>1;
if (mid==dividend)
{
if (signal<0)
return -k;
else
return k;
}
else
{
if (mid<dividend)
{
start = mid;
i = k;
}
else
{
end = mid;
j = k;
}
}
}
}
}
下面这方法就牛逼多了,还是那句话“自惭形秽,望尘莫及”。也是用了移位运算,比我的算法牛逼的地方在于:该算法在查找结果集区间的时候就已经进行了运算使得被除数不断的减小,结果不断的累积。(这里最关键的是要知道:除法运算的定义,即减了几次被除数,结果就增加几),当到达区间界限时,从头再来,继续同样处理,此时被除数已经减少了很多,结果也已经积累了很多。直到被除数小于除数。真是漂亮!如下:

int divide(int dividend, int divisor) {
// Note: The Solution object is instantiated only once.
long long a = abs((double)dividend);
long long b = abs((double)divisor);
long long res = 0;
while(a >= b)
{
long long c = b;
for(int i = 0; a >= c; i++, c <<=1)
{
a -= c;
res += 1<<i;
}
}
return ((dividend ^ divisor) >> 31) ? (-res) : (res);
}


还有一点更值得注意:为什么用long long a = abs((double)dividend); ?不用真不行,因为最小负数直接取绝对值时会溢出(记得吗8位运算最小负数为-128,最大正数为127),所以要用double转化,还要用long long,所有涉及溢出的处理都是用long long解决的,strToInt这题也是。

by the way题目不懂时我都会找这位大神/article/2750079.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: