LeetCode(29) - Divide Two Integers
这道题要求的是完成整数的除法运算,不能用乘除和mod来求。既然不能够用乘除和取模,能用的就只有加减和位移。
思路比较抽象,直接说不好理解,举个例子,假设被除数是28,除数是5,则在第一个循环里,我们需要找到2^n满足2^n * 5 < 28,事实上我们知道,当n=2时,有4*5 = 20, n = 3时,8*5 = 40,所以我们n取2,得到28至少有4个5相加,此时28-20 = 8。重新再走循环,得到8有一个5相加,此时8-5*1=3。因为3小于5,所以循环结束,综合两次循环我们可以得到,28最多只能有4(第一次循环)+ 1(第二次循环)个5相加,所以答案就是4+1 = 5。至于2^n不用乘法怎么得到呢?—— 通过左移。
当然还要注意一些边界条件,包括Integer.MIN_VALUE / -1的时候,得到的值会溢出等等。
代码如下:
1 public class Solution { 2 public int divide(int dividend, int divisor) { 3 //被除数为0或者Integer.MIN_VALUE / -1的情况。 4 if (divisor == 0 || (dividend == Integer.MIN_VALUE 5 && divisor == -1)) return Integer.MAX_VALUE; 6 int res = 0; 7 //符号 8 int sign = (dividend > 0 && divisor < 0) || (dividend < 0 && divisor > 0)? -1 : 1; 9 //取long防止计算中溢出 10 long a = Math.abs((long)dividend); 11 long b = Math.abs((long)divisor); 12 //等号不能省略。 13 while (a >= b) { 14 long multi = 1; 15 long cur = b; 16 //每次循环curr每左移一次,就等于乘以2 17 while (a >= cur) { 18 cur <<= 1; 19 //记录2^n 20 multi <<= 1; 21 } 22 //因为上面循环超过a,故右移回去一位, 23 cur >>= 1; 24 multi >>= 1; 25 a -= cur; 26 res += (int)multi; 27 multi = 0; 28 } 29 return res * sign; 30 } 31 }