給定兩個整數,被除數 dividend 和除數 divisor。將兩數相除,要求不使用乘法、除法和 mod 運算符。git
返回被除數 dividend 除以除數 divisor 獲得的商。github
示例 1:bash
輸入: dividend = 10, divisor = 3
輸出: 3
複製代碼
示例 2:ide
輸入: dividend = 7, divisor = -3
輸出: -2
複製代碼
說明:ui
解題思路來自評論區的foxleezh大神。題目中明確不能使用/
, 咱們能夠右移模擬除法,右移能夠等價於下面的等式spa
a / 2 === a >> 1
a / 4 === a >> 2
a / 8 === a >> 3
複製代碼
被除數 / 除數 === 商……餘數
等價於 ➡️ 被除數 === (商 * 除數) + 餘數
等價於 ➡️ (被除數 - 餘數) / 商 === 除數
code
假設,咱們的被除數等於100,除數等於5。get
根據等式(被除數 - 餘數) / 商 == 除數
,咱們首先要找到,100除以多少最接近於除數(或者說,除以多少時會大於等於除數)。it
當100除以2^31時,結果相較於除數會很是的小。咱們使用循環逐漸減小右移的位數,逐漸逼近除數,當100 >>> 4(100 / 16)時等於6,大於等於5。io
這時,咱們能夠確定**商是大於16(2的四次方)**的某個數(或者說,100至少包含16個5)。
咱們使用被除數 = 被除數 - 16 * 除數
等於還剩下的沒有除乾淨的數。目前還剩下20。咱們再次使用上述的方法,再次逼近除數(獲取20裏還有幾個5)。最終獲得最後的結果。
/** * @param {number} dividend * @param {number} divisor * @return {number} */
var divide = function(dividend, divisor) {
// 判斷結果是否爲負數
const isNegative = (dividend ^ divisor) < 0
// 統一按正數處理
dividend = Math.abs(dividend)
divisor = Math.abs(divisor)
if (dividend === 0) {
return 0
}
if (dividend === 2147483648 && divisor === 1) {
// 避免結果溢出
return isNegative ? -dividend/divisor : dividend/divisor - 1
}
let result = 0
for (let i = 31; i >= 0; i--) {
// 注意這裏須要使用無符號右移
if ((dividend >>> i) >= divisor) {
result += Math.pow(2, i)
dividend -= Math.pow(2, i) * divisor
}
}
return isNegative ? -result : result
};
複製代碼