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 }
注意:
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 }
簡化一點:

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 }
GitHub Code:
Ref: http://blog.csdn.net/fightforyourdream/article/details/16899675