LeetCode: Divide Two Integers 解题报告

Divide Two Integers

LeetCode: Divide Two Integers 解题报告
Divide two integers without using multiplication, division and mod operator.

SOLUTION 1
1. 基本思想是不断地减掉除数,直到为0为止。但是这样会太慢。

2. 我们可以使用2分法来加速这个过程。不断对除数*2,直到它比被除数还大为止。加倍的同时,也记录下cnt,将被除数减掉加倍后的值,并且结果+cnt。

因为是2倍地加大,所以速度会很快,指数级的速度。

3. 另外要注意的是:最小值的越界问题。对最小的正数取abs,得到的还是它。。。 因为最小的正数的绝对值大于最大的正数(INT)

所以,我们使用Long来接住这个集合就可以了。

 1 public class Solution {

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

 3         long a = Math.abs((long)dividend);

 4         

 5         // ref : http://blog.csdn.net/kenden23/article/details/16986763

 6         // Note: 在这里必须先取long再abs,否则int的最小值abs后也是原值

 7         long b = Math.abs((long)divisor);

 8         

 9         int ret = 0;

10         // 这里必须是= 因为相等时也可以减

11         while (a >= b) {

12             // 判断条件是 >=

13             for (long deduce = b, cnt = 1; a >= deduce; deduce <<= 1, cnt <<= 1) {

14                 a -= deduce;

15                 ret += cnt;

16             }

17         }

18         

19         // 获取符号位。根据除数跟被除数的关系来定

20         return (dividend > 0) ^ (divisor > 0) ? -ret: ret;

21     }

22 }
View Code

注意:

1. C,java中的右移运算,是带符号位的,叫算术右移http://www.cppblog.com/tx7do/archive/2006/10/19/13867.html

2015.1.3 redo:

Leetcode又加强了一大堆边界条件运算,所以我们代码也要更改:

1. 返回值的时候,判断是不是越界,越界返回最大值。

例子:

Input: -2147483648, -1
Expected: 2147483647

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

 2         if (divisor == 0) {

 3             return Integer.MAX_VALUE;

 4         }

 5         

 6         // Note: 在这里必须先取long再abs,否则int的最小值abs后也是原值

 7         long dividendTmp = Math.abs((long)dividend);

 8         long divisorTmp = Math.abs((long)divisor);

 9         

10         // bug 3: ret should use Long to avoid overflow.

11         long ret = 0;

12         // bug 2: should use dividentTmp > divisor as the while judge.

13         while (dividendTmp >= divisorTmp) {

14             // bug 1: should use Long for tmp.

15             long tmp = divisorTmp;

16             int rst = 1;

17             while(tmp <= dividendTmp) {

18                 // bug 3: the two statement should inside the while LOOP.

19                 ret += rst;

20                 dividendTmp -= tmp;

21                 

22                 tmp <<= 1;

23                 rst <<= 1;

24             }

25         }

26         // bug 4: out of range:

27         /*

28         Input:    -2147483648, -1

29         Output:    -2147483648

30         Expected:    2147483647

31         */

32         //ret = ((dividend > 0) ^ (divisor > 0)) ? -ret: ret;

33         ret = ((((dividend ^ divisor) >> 31) & 1) == 1) ? -ret: ret;

34         

35         if (ret > Integer.MAX_VALUE || ret < Integer.MIN_VALUE) {

36             return Integer.MAX_VALUE;

37         } else {

38             return (int)ret;

39         }

40     }
View Code

简化一点:

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

 2         long a = Math.abs((long)dividend);

 3         long b = Math.abs((long)divisor);

 4         

 5         long ret = 0;

 6         

 7         while (a >= b) {

 8             for (long tmp = b, cnt = 1; a >= tmp; tmp <<= 1, cnt <<= 1) {

 9                 ret += cnt;

10                 a -= tmp;

11             }

12         }

13         

14         ret = (((dividend ^ divisor) >> 31) & 1) == 1 ? -ret: ret;

15         if (ret > Integer.MAX_VALUE || ret < Integer.MIN_VALUE) {

16             return Integer.MAX_VALUE;

17         }

18         

19         return (int)ret;

20     }
View Code

 

GitHub Code:

divide.java

 

Ref: http://blog.csdn.net/fightforyourdream/article/details/16899675

你可能感兴趣的:(LeetCode)