演算法練習--LeetCode--29. Divide Two Integers: 100%

Crazy凡發表於2019-01-04
  1. Divide Two Integers

Given two integers dividend and divisor, divide two integers without using multiplication, division and mod operator. Return the quotient after dividing dividend by divisor. The integer division should truncate toward zero.

Example 1:

Input: dividend = 10, divisor = 3 Output: 3

Example 2:

Input: dividend = 7, divisor = -3 Output: -2

Note:

  • Both dividend and divisor will be 32-bit signed integers.
  • The divisor will never be 0.
  • Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−231, 231 − 1]. For the purpose of this problem, assume that your function returns 231 − 1 when the division result overflows.

簡單來說就是不用***‘乘法’、‘除法’和‘取餘’運算***來求兩個整數的商,注意結果要在 [−231, 231 − 1]

Round One

  • 暴力減法(如下),我賭5毛,超時(Time Limit Exceeded)!
// Swift Code
class Solution {
    func divide(_ dividend: Int, _ divisor: Int) -> Int {
        let sign = (dividend >= 0) == (divisor > 0) ? 1 : -1
        var dividend = abs(dividend)
        let divisor = abs(divisor)
        var result = 0
        while dividend > divisor {
            dividend -= divisor
            result += 1
        }
        if dividend == divisor {
            result += 1
        }
        return sign < 0 ? -result : result
    }
}
複製程式碼

Round Two

一個一個減肯定是超時了,要是一批一批減呢?

所以就需要先成倍放大被除數,不允許用***‘乘法’、‘除法’和‘取餘’*** 還有 ‘<<’、‘>>’

這個方法耗時少於超越了100%的其它Swift提交

// Swift Code
class Solution {
    func divide(_ dividend: Int, _ divisor: Int) -> Int {
        // 除數、被除數符號不一致時候商為負數
        let sign = (dividend >= 0) == (divisor > 0) ? 1 : -1

        // 擴大下資料型別,避免溢位
        var _dividend = Int64(abs(dividend))
        let _divisor = Int64(abs(divisor))

        var result = 0
        var temp = 1
        var _divisor_temp = _divisor

        // 放大被除數
        while _divisor_temp < _dividend {
            _divisor_temp = _divisor_temp << 1
            temp = temp << 1
        }

        // 在合理範圍內縮小被放大的被除數
        while _divisor_temp > 0, _divisor_temp > _divisor {
            while _divisor_temp > _dividend {
                _divisor_temp = _divisor_temp >> 1
                temp = temp >> 1
            }
            _dividend -= _divisor_temp
            result += temp
        }

        // 竟然一樣大,所以再來一次了
        if _dividend == _divisor {
            result += 1
        }

        // 結果是有範圍限制的
        return sign < 0 ? max(-result, Int(Int32.min)) : min(result, Int(Int32.max))
    }
}
複製程式碼

TestCase

// Swift Code
assert(Solution().divide(10, 3) == 3)
assert(Solution().divide(3, 3) == 1)
assert(Solution().divide(1, 1) == 1)
assert(Solution().divide(2, 3) == 0)
assert(Solution().divide(7, -3) == -2)
assert(Solution().divide(-2147483648, -1) == 2147483647)
assert(Solution().divide(0, 2147483648) == 0)
複製程式碼

相關文章