leetcode29_Divide Two Integers

橘子oly發表於2016-10-24

一.問題描述

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

If it is overflow, return MAX_INT.

實現兩個int的除法,程式碼中不能使用乘、除和取餘操作,溢位時返回max_int。

二.程式碼編寫

    最基本的想法是一直迴圈減,但明顯效率不高,有可能會TLE。所以考慮用移位的思想,每一位還是用減法,這種思想基本上就跟我們手算除法一致,程式碼如下:

class Solution(object):
    def divide(self, dividend, divisor):
        """
        :type dividend: int
        :type divisor: int
        :rtype: int
        """
        re_str = ''
        sign = (dividend < 0 and divisor > 0) or (dividend > 0 and divisor < 0) 
        dividend, divisor = abs(dividend), abs(divisor)
        jinwei = 0
        for i in str(dividend):
            n = int(str(jinwei)+i)
            re_cha = 0
            while n>=divisor:
                re_cha += 1
                n -=divisor
            re_str += str(re_cha)
            jinwei = n
        ret = int(re_str) if sign ==0 else -int(re_str)
        return min(max(-2147483648, ret), 2147483647) 


三.程式碼優化

@ update at 2017.03.04  在lintcode上做了一道一樣的題。

用的移位shift的方式,

前言

這道題之前在leetcode上做過,Divide Two Integers
當時完全沒想到二分的做法,最初想的是不能用乘除法,就用減法,直接用被除數迴圈減除數,這樣會TLE。優化的方法是按位去減法,移位,具體的思路其實跟我們手算除法是一模一樣的。

二分法

  • 就算提示了是二分,也沒想到到底如何而二分- -。程式碼參考了九章演算法,用移位shift的思想。個人感覺沒看到二分的思想- -
  • 除法本質上就是移位的思想吧
  • shift x即 x << n結果等於 x * (2 ^ n)

eg

100 / 9 ==> 9 * (2^3) + 9 * (2^1) + 9 * (2^0)

具體程式碼如下:

class Solution:
    # @param {int} dividend the dividend
    # @param {int} divisor the divisor
    # @return {int} the result
    def divide(self, dividend, divisor):
        # Write your code here
        # for we cannot use multiplication&division, we use shift
        # neg_flag is True when result is negative, else False
        neg_flag = (dividend > 0 and divisor < 0) \
            or (dividend < 0 and divisor > 0)
        dividend_a, divisor_a = abs(dividend), abs(divisor)
        # 100 / 9 ==>  9 *  (2^3) + 9 * (2^1) + 9 * (2^0), then
        # result = 2^3 + 2^1 + 2^0 = 11
        result, shift = 0, 31
        while shift >= 0:
            if dividend_a >= divisor_a << shift:
                dividend_a -= divisor_a << shift
                result += 1 << shift  # result += 2^shift
            shift -= 1
        if neg_flag:
            result = -result
        if result > 2147483647:
            return 2147483647
        return result
        # TODO: dont forget the negative
        # TODO: check for overflow
附:lintcode上給這道題的標籤是二分,但是我個人沒看出來二分的思想- -



相關文章