Leetcode: Divide Two Integers

Divide two integers without using multiplication, division and mod operator.

第二遍做法:只有一种情况整数除以整数会overflow,那就是Integer.MIN_VALUE除以-1,这种情况特殊分析。

之所以要用long a, b代替dividend和divisor是因为:比如Integer.MAX_VALUE除以1,第21行的while循环,1不管怎么右移,因为是整数,永远无法比Integer.MAX_VALUE大。所以会一直死循环。所以被除数和除数都用Long型,但是result不能用Long型,因为返回的时候会报错:原因是损失精度

 1 public class Solution {

 2     public int divide(int dividend, int divisor) {

 3         if (dividend==Integer.MIN_VALUE && divisor==-1) return Integer.MAX_VALUE;

 4         boolean isNeg = false;

 5         long a = dividend;

 6         long b = divisor;

 7         if (b == 0)

 8             throw new ArithmeticException();

 9         if (a < 0) {

10             isNeg = !isNeg;

11             a = -a;

12         }

13         if (divisor < 0) {

14             isNeg = !isNeg;

15             b = -b;

16         }

17         long num = a;

18         int res = 0;

19         while (num >= b) {

20             int i = 0;

21             while (num >= (b<<i)) {

22                 i++;

23             }

24             res |= 1<<(i-1);

25             num -= b<<(i-1);

26         }

27         return isNeg? -res : res;

28     }

29 }

Analysis: 我自己用binary search做老是出TLE的错误,看了网上思路,有了如下方法:long a = dividend, long b = divisor; 我们发现 a 可以表示为 a = b * 2^k + b * 2 ^m + ....+ C, 那么商可以表示为 2^k + 2^m + .... 要想找到商,那么我们需要依次去找出k, m ... 。 观察得知,b*2^k 表示把divisor b左移k位(即b<<k), 而且b<<k+1就会大于a,根据这个性质,我们可以找出k,即一直把b左移一位直到b大于a为止,这样移动的结果比如(b<<x)  > a, 那么x-1就是我们要找的k. 构造商的话,我们就定义一个int res, res |= 1<<k

参考了http://jqmichelle.blogspot.com/2013/05/leetcode-divide-two-integers-divide-two.html 的思路

 1 public class Solution {

 2     public int divide(int dividend, int divisor) // return c=a/b;

 3     {

 4         long a = dividend;

 5         long b = divisor;

 6 

 7         if (b == 0)

 8             throw new ArithmeticException();

 9 

10         boolean isNeg = false;

11         if (a < 0)   

12             isNeg = !isNeg;

13 

14         if (b < 0)

15             isNeg = !isNeg;

16 

17         a = Math.abs(a);

18         b = Math.abs(b);

19 

20         int k = 0;

21         while ((b<<k) <= a)   //until (b<<k) > a, (b<<k-1) <= a

22             ++k;

23 

24         int res = 0;

25         for (int i = k-1; i >= 0; i--) //start from k-1 to 0, because (b<<k-1) is the first smaller than a, b left shift k means result has a 1 at this bit(left shift k)

26         {

27             if (b << i <= a)

28             {

29                 res |= 1 << i;

30                 a -= b << i;  //find out all the 1s for result.

31             }

32         }

33 

34         if (isNeg)

35             res = -res;

36         return res;

37     }

38 

39 }

你可能感兴趣的:(LeetCode)