學渣帶你刷Leetcode0029兩數相除

2021-10-05 05:17:32 字數 2681 閱讀 4957

給定兩個整數,被除數 dividend 和除數 divisor。將兩數相除,要求不使用乘法、除法和 mod 運算子。

返回被除數 dividend 除以除數 divisor 得到的商。

整數除法的結果應當截去(truncate)其小數部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2

示例 1:

輸入: dividend = 10, divisor = 3

輸出: 3

解釋: 10/3 = truncate(3.33333..) = truncate(3) = 3

示例 2:

輸入: dividend = 7, divisor = -3

輸出: -2

解釋: 7/-3 = truncate(-2.33333..) = -2

被除數和除數均為 32 位有符號整數。

除數不為 0。

假設我們的環境只能儲存 32 位有符號整數,其數值範圍是 [−231,  231 − 1]。本題中,如果除法結果溢位,則返回 231 − 1。

太能難為人了,為啥還說是中等的題,2個事不讓用,這不讓用,那也不讓用。【被除數】 除以【除數】得的結果是啥,取整直接要最後結果就好了。

(1)n/m==k+r(r==n mod m),也就是我們小學學過的被除數除以除數等於商加餘數。根據這個公式很自然的想到用n逐次減去m直到差小於m,**如下;

int i=0;

while (n>=m) 

return i;

(2)

例:a = a*9;   b = b*7;

(1)a = a*9可以拆分為a*(8+1),即a*8 + a*1,因此可以改為a = (a << 3) + a;

(2)b = b*7可以拆分為b*(8-1),即b*8 - b*1,因此可以改為b = (b << 3) - b;

計算機是乙個二元的世界,所有的int型資料都可以用[2^0, 2^1,…,2^31]這樣一組基來表示(int型最高31位)。不難想到用除數的2^31,2^30,…,2^2,2^1,2^0倍嘗試去比較被除數,如果減得動(被除數大),則把相應的倍數加到商中;如果減不動,則依次嘗試更小的倍數。這樣就可以快速逼近最終的結果。不讓用乘除法就用移位相當於乘除2。

是不是還是雲裡霧裡的。致敬80後電視劇集的回憶《像霧像雨又像風》。

如果上面的理解不了,看這裡

28/3      (1)試探  28>(2^3)*3       這裡面包含了8個3     還剩下28-(2^3)*3的數需要處理裡面有多少個3

(2)4>(2^0)*3         這裡面包含了1個3       試探到0了,就木有了

2的i次方其實就相當於左移i位,為什麼從31位開始呢?因為int型資料最大值就是2^31啊。

首先不能使用乘法、除法和mod運算,我們想到可以使用減法來實現除法,但是我們會發現減法的效率很低。

除了這些操作,我們知道,位運算也可以表示乘法和除法,只是乘除的都是2的冪。

通過除法公式:dividend / (2^n) = divisor + 餘數;

我們知道了:dividend / (2^n) >= divisor時,餘數:dividend - divisor*(2^n),

此時相當於dividend / divisor = 2^n.

則商就是滿足情況的所有2^n的和。

注意

詳細解釋關注 b站  【c語言全**】學渣帶你刷leetcode 不走丟 

#include #include #include #define int_max0 0x7fffffff   //0111 1111 1111 1111 1111 1111 1111 1111

#define int_min0 0x80000000 // 1000 0000 0000 0000 0000 0000 0000 0000

#define int_max 2147483647

#define int_min -2147483648

int divide(int dividend, int divisor)

if((dividend<0&&divisor>0)||(dividend>0&&divisor<0))

if(dividend == int_min) // 若被除數為int_min,先減一次,在再進行運算

int t = abs(dividend);

int d = abs(divisor);

int i;

for( i = 31; i >= 0; i--)

// printf("\n");

}return sign ? -result : result;

}int main()

學渣帶你刷Leetcode0035搜尋插入位置

給定乙個排序陣列和乙個目標值,在陣列中找到目標值,並返回其索引。如果目標值不存在於陣列中,返回它將會被按順序插入的位置。你可以假設陣列中無重複元素。示例 1 輸入 1,3,5,6 5 輸出 2 示例 2 輸入 1,3,5,6 2 輸出 1 示例 3 輸入 1,3,5,6 7 輸出 4 示例 4 輸入...

學渣帶你刷Leetcode0063不同路徑 II

乙個機械人位於乙個 m x n 網格的左上角 起始點在下圖中標記為 start 機械人每次只能向下或者向右移動一步。機械人試圖達到網格的右下角 在下圖中標記為 finish 現在考慮網格中有障礙物。那麼從左上角到右下角將會有多少條不同的路徑?網格中的障礙物和空位置分別用 1 和 0 來表示。說明 m...

學渣帶你刷Leetcode0066加一

給定乙個由整數組成的非空陣列所表示的非負整數,在該數的基礎上加一。最高位數字存放在陣列的首位,陣列中每個元素只儲存單個數字。你可以假設除了整數 0 之外,這個整數不會以零開頭。示例 1 輸入 1,2,3 輸出 1,2,4 解釋 輸入陣列表示數字 123。示例 2 輸入 4,3,2,1 輸出 4,3,...