您的位置:首页 > 其它

LeetCode - 29. Divide Two Integers

2016-07-13 16:12 375 查看
这道题目要求我们在不适用乘除和模运算的情况先实现两个数的除法,那么这种情况下我们自然就会想到使用bit manipulation,我们来思考一下应该怎样使用bit manipulation:

假设对于15和3的除法,其中15是被除数,3是除数。除法的本质就是计算在被除数当中有多少个除数,所以我们首先用15 - 3 = 12,结果大于3,那我们接下来就减去更多。因为不能使用乘法,所以我们将3进行左移,3 << 1,相当于3 * 2,此时12 - 6 = 6仍然大于3,接着我们再把除数左移,得到24,此时15小于24。因为12是将3左移两次得到的,而12 = 3 * 4,所以我们想要的到这个4,这样就可以记录下被除数中到底有多少个除数,这里我们从1开始,每当需要把除数左移的时候,我们同样将1左移,这样左移两次后得到的结果就是4。上面的过程也就相当于15
= 3 * 4 + 3,这时我们已知的是被除数15中含有4个除数和一个3。

重复上面的过程,我们用被除数3减去除数3,得到0,这时我们的算法已经完成,只需要将结果加上1即可。

根据题意,我们还要处理溢出的情况,在这道题目中,溢出有可能在两种情况下出现:

1. 除数 = 0

2. 被除数为int的最小值,而此时除数为-1,因为Math.abs(Integer.MIN_VALUE) = Math.abs(Integer.MAX_VALUE) + 1

整体的代码如下:

public class Solution {
public int divide(int dividend, int divisor) {
if(dividend == 0) return 0; // corner case

// Handle overflow
if(divisor == 0 || (dividend == Integer.MIN_VALUE && divisor == -1)){
return Integer.MAX_VALUE;
}

int sign = ((dividend < 0) ^ (divisor < 0)) ? -1 : 1;
long dvd = Math.abs((long)dividend);
long dvs = Math.abs((long)divisor);
int result = 0;

// Iteratively dvs * 2 and subtract it from dvd
while(dvd >= dvs){
long temp = dvs;
int multiple = 1;
while(dvd >= (temp << 1)){
multiple <<= 1; // record # of dvs
temp <<= 1; // temp * 2
}
dvd -= temp;
result += multiple;
}

return sign < 0 ? -result : result;
}
}

知识点:

1. 记住这种用位运算实现除法的算法

2. 记下在除法中可能会出现溢出的两种情况,除数为0,或者在被除数为int最小值的情况下除数为-1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息