29. 兩數相除(Python)

更多精彩內容,請關注【力扣中等題】

題目

難度:★★☆☆☆
類型:數學

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

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

說明

被除數和除數均為 32 位有符號整數。
除數不為 0。
假設我們的環境只能存儲 32 位有符號整數,其數值范圍是 [?231, 231 ? 1]。本題中,如果除法結果溢出,則返回 231 ? 1。

示例

示例 1
輸入: dividend = 10, divisor = 3
輸出: 3

示例 2
輸入: dividend = 7, divisor = -3
輸出: -2

解答

方案1:二分法

由于商不會大于被除數,因此可以把題目當做一個查找問題,就可以使用二分法解決。在程序開始,首先要對結果到的正負號進行判斷,并將被除數和輸出取絕對值。類似題目【題目69. x的平方根】

  1. 構建一個連續遞增數組,數組最小值為零,最大值為被除數divident,并取出該數組最中間的元素mid(如果數組有偶數個元素,我們取中點偏左的數字);

  2. 查看mid*divisor,(mid+1)*divisor與被除數的關系,分一下三種情況:
    (1)dividend < mid*divisor,表明中點處的元素過大,拋棄數組右半部分;
    (2)mid*divisor <= dividend < (mid+1)*divisor,表明中點處的元素即為所求,直接返回;
    (3)(mid+1)*divisor <= dividend,表明中點處的元素過小,拋棄數組右半部分;

  3. 每次迭代,都要更新數組并取新的中點。

class Solution:
    def divide(self, dividend: int, divisor: int) -> int:

        # 確定結果的正負
        flag = 1 if divisor > 0 and dividend > 0 or divisor < 0 and dividend < 0 else -1

        # 操作數取絕對值
        dividend, divisor = abs(dividend), abs(divisor)

        # 初始化上下邊界
        low, upper = 0, dividend

        # 執行循環
        while low <= upper:
            # 二分查找中點
            middle = (low + upper) // 2
            # 情況1,中點*除數>被除數,說明中點處值偏大,拋棄右半部分
            if dividend < middle * divisor:
                upper = middle - 1

            # 情況2,(中點+1)*除數<被除數,說明中點處的值偏小,拋棄左半部分
            elif (middle + 1) * divisor <= dividend:
                low = middle + 1

            # 情況3,中點+1 * 除數 < 被除數 < (中點+1) * 除數,獲得商,并限制取值范圍
            elif middle * divisor <= dividend < (middle + 1) * divisor:
                return min(max(-2 ** 31, flag * middle), 2 ** 31 - 1)

如有疑問或建議,歡迎評論區留言~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。