leetcode-【中等題】Divide Two Integers

題目ide

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

If it is overflow, return MAX_INTspa

連接.net

https://leetcode.com/problems/divide-two-integers/3d

答案code

1、int的最大值MAX_INT爲power(2,31)-1 = 2147483647blog

2、int的最小值MIN_INT爲-power(2,31) = -2147483648ip

3、當MIN_INT除以-1的時候,發生溢出,由於獲得的值大於MAX_INTleetcode

4、有符號數的最高位爲1時,表示負數,因此可使用異或運算得到商的符號rem

5、abs的各類版本看這裏,double abs(double),long abs(long)居然在C++中有,其實我想本身寫個求絕對值方法的,不過,手抖仍是搜了一下abs的原型。

6、這纔是重中之重,剛開始看到題目,我不知道怎麼用位運算去實現除法,先搜到答案

而後思考其中的原理,爲何能夠這麼作,思考以後本身才寫了代碼。

個人推理以下,若有問題,請指出,謝謝。下面我有^表示指數,不要跟C++中的^弄混了。

a = b * x (x爲要求的商,等號應該爲約等於,其實嘛,應該是a >= b * x && a < b * (x+1))

任何一個整數是能夠用二進制表示的,因此x=2^m + 2^n + ...... + 2^t,其中m > n > t,m,n,t爲整數。

x還能夠這麼表示x = 1*2^m + 0 * 2^(m-1) + 1 * 2^(m-2) + ...... + (1或0)*2^0。

事實上x還能夠這麼表示:

x = (2^k + 2^(k-1) + ...... + 2^0) + (2^t + 2^(t-1) + ...... + 2^0) + ...... + (2^r + 2^(r-1) + ...... + 2^0),其中k > t > ...... > r。

因此 a = b * (2^k + 2^(k-1) + ...... + 2^0) +b *  (2^t + 2^(t-1) + ...... + 2^0) + ...... + b * (2^r + 2^(r-1) + ...... + 2^0).

而且k,t,r等知足如下關係:

b *  (2^t + 2^(t-1) + ...... + 2^0) + ...... + b * (2^r + 2^(r-1) + ...... + 2^0)  < b * (2^k + 2^(k-1) + ...... + 2^0) 

...... + b * (2^r + 2^(r-1) + ...... + 2^0) < b * (2^k + 2^(k-1) + ...... + 2^0)  - b *  (2^t + 2^(t-1) + ...... + 2^0)

第一次是 a - b * (2^k + 2^(k-1) + ...... + 2^0)  = b *  (2^t + 2^(t-1) + ...... + 2^0) + ...... + b * (2^r + 2^(r-1) + ...... + 2^0)

對b進行不斷左移,即上式的橙色部分,而並累加位移(2^x')是x的一部分,將a不斷減去不斷左移後的b,便可獲得等式左邊的數據。

a - b * (2^k + 2^(k-1) + ...... + 2^0)  < b * (2^k + 2^(k-1) + ...... + 2^0) 

即b *  (2^t + 2^(t-1) + ...... + 2^0) + ...... + b * (2^r + 2^(r-1) + ...... + 2^0) < b * (2^k + 2^(k-1) + ...... + 2^0) 

這個是必然成立的,若是不成立,則b還能夠繼續左移,即k的值要比當前達到的k還要大,故每次a處理後的結果會比b處理後的結果要小。

第二次a - b * (2^k + 2^(k-1) + ...... + 2^0) - b *  (2^t + 2^(t-1) + ...... + 2^0) = ...... + b * (2^r + 2^(r-1) + ...... + 2^0)

藍色部分爲第一次的結果。

推到這裏,你們應該懂了

代碼

 1 class Solution {
 2 public:
 3     static const int MAX_INT = 2147483647;
 4     static const int MIN_INT = -2147483648;
 5     
 6     int divide(int dividend, int divisor) {
 7         if(dividend == MIN_INT && divisor == -1)
 8         {
 9             return MAX_INT;
10         }
11         
12         long pre = abs((long)dividend);
13         long post = abs((long)divisor);
14         int index;
15         int rem = 0;
16         
17         while(pre >= post)
18         {
19             long tmp = post;
20             for(index = 0; pre >= tmp; index ++, tmp <<= 1)
21             {
22                 pre -= tmp;
23                 rem += (1 << index);
24             }
25         }
26         
27         return (dividend >> 31) ^ (divisor >> 31) ? -rem:rem;
28     }
29 };
View Code
相關文章
相關標籤/搜索