【LeetCode】29. Divide Two Integers 解题报告(Python)

题目分析:

这一题是有一点难度,它的意思是让算两个数相除的商,但是不能使用乘法,除法和mod运算。一开始想到循环相减,但是数据范围在[−231, 231 − 1]。减法会TLE,参考了这篇博客发现可以用移位操作代替乘法。主要方法如下:

  1. 被除数/除数=商 (忽略余数)=> 被除数=除数*商。

  2. 商(任意整数)可以表示为:a_0 * 20+a_1 * 21+…+a_i * 2i+…+a_n * 2n.

  3. 在python中左移操作<<相当于对一个数乘以2,右移操作相当于除以2.

  4. 我们让除数左移直到大于被除数前的的一个数,例如计算28/3,我们进行三次左移操作,使3 * 2 * 2 * 2=3 * 8=24<28(注意四次左移操作得到3 * 24=48>28).记录下2 * 2 * 2=23=8.

  5. 我们让28减去24得到4,然后像第四步一样计算4/3,则3 * 20=3<4.记录下20=1.

  6. 由于4-3=1小于除数3,停止计算,并将每轮得到的值相加,在本例中8+1=9,记得到商(即28/3=9)。

至此,程序的主题思想已经介绍完了,接下来要注意数据左移和求整数绝对值的边界问题。

代码说明:
1、被除数与除数异号时记录一下
if (dividend < 0 and divisor > 0) or (dividend > 0 and divisor < 0): flag = -1
2、如题目分析4

 while(dividend >= divisor << n):
                n += 1
            res += 1 << (n - 1)

3、如题目分析5
dividend -= (divisor << (n - 1))
4、把正负号加上并判断是否越界

res = -res if flag < 0 else res
        if res < -2147483648 or res > 2147483647:
            return 2147483647

测试代码:

class Solution:
    def divide(self, dividend, divisor):
        res, flag = 0, 0
        if (dividend < 0 and divisor > 0) or (dividend > 0 and divisor < 0):
            flag = -1
        dividend = abs(dividend)
        divisor = abs(divisor)
        while(dividend >= divisor):
            n = 0
            while(dividend >= divisor << n):
                n += 1
            res += 1 << (n - 1)
            dividend -= (divisor << (n - 1))
        res = -res if flag < 0 else res
        if res < -2147483648 or res > 2147483647:
            return 2147483647
        return res

print(Solution().divide(-2147483648, 1))    #提交时请删除该行

参考博客

猜你喜欢

转载自blog.csdn.net/L141210113/article/details/88306238