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 }

 

posted @ 2016-03-16 13:45  可普CS之家  阅读(206)  评论(0编辑  收藏  举报