zoukankan      html  css  js  c++  java
  • [LeetCode] 29. 两数相除

    题目链接: https://leetcode-cn.com/problems/divide-two-integers/

    题目描述:

    给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。

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

    示例:

    示例 1:

    输入: dividend = 10, divisor = 3
    输出: 3
    

    示例 2:

    输入: dividend = 7, divisor = -3
    输出: -2
    

    说明:

    • 被除数和除数均为 32 位有符号整数。
    • 除数不为 0。
    • 假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231 − 1]。本题中,如果除法结果溢出,则返回 231 − 1。

    思路:

    当然这道题,可以作弊过,

    但是,过不是我们的目的,而是要提高我们的编程水平!所以做好每一题!

    这道题换句话说: 除数能减去多少个被除数.

        def divide(self, divd: int, dior: int) -> int:
            res = 0
            sign =  1 if divd ^ dior > 0 else -1
            divd = abs(divd)
            dior = abs(dior)
            while divd >= dior:
                res += 1
                divd -= dior
            res = res*sign 
            return min(max(-2**31, res), 2**31-1)
    

    上面就是我们简单想法,但是有个问题,当被除数为2147483648,除数为1,必然超时?

    那么该怎么办呢?我们接着上面的想法继续往下想!

    我们直接举个例子如果被除数15,除数3,用我们上面的方法要遍历5

    接下来,我们使用不断增倍除数

    比如:

    被除数 除数

    15 3

    12 6

    6 12

    发现除数大于被除数大,再重现开始

    6 3

    ...

    3 3

    虽然这个例子遍历次数相等,对于较大的数,可以减少时间复杂度.


    关注我的知乎专栏,了解更多的解题技巧,大家一起进步,加油!

    代码:

    python

    class Solution:
        def divide(self, divd: int, dior: int) -> int:
            res = 0
            sign =  1 if divd ^ dior >= 0 else -1
            #print(sign)
            divd = abs(divd)
            dior = abs(dior)
            while divd >= dior:
                tmp, i = dior, 1
                while divd >= tmp:
                    divd -= tmp
                    res += i
                    i <<= 1
                    tmp <<= 1
            res = res * sign 
            return min(max(-2**31, res), 2**31-1)
    

    java

    class Solution {
        public int divide(int dividend, int divisor) {
            int sign = (dividend ^ divisor) >> 31;
            long lDividend = Math.abs((long) dividend);
            long lDivisor = Math.abs((long) divisor);
            long res = 0;
            while (lDividend >= lDivisor){
                long tmp = lDivisor;
                long i = 1;
                while (lDividend >= tmp){
                    lDividend -= tmp;
                    res += i;
                    i <<= 1;
                    tmp <<= 1;
                }
            }
            if (sign == -1) res *= -1;
            if (res < Integer.MIN_VALUE) return Integer.MIN_VALUE;
            else if (res > Integer.MAX_VALUE) return Integer.MAX_VALUE;
            return (int)res;
            
        }
    }
    

    作弊过!嘻嘻

    作弊一

    class Solution:
        def divide(self, divd, dior):
            """
            :type dividend: int
            :type divisor: int
            :rtype: int
            """
            sign =  1 if divd ^ dior >= 0 else -1
            res = abs(divd) // abs(dior)
            res *= sign
            return min(max(-2**31, res), 2**31-1)
    

    作弊二

    class Solution(object):
        def divide(self, dividend, divisor):
            """
            :type dividend: int
            :type divisor: int
            :rtype: int
            """
            self.dividend = dividend
            self.divisor = divisor
    
            a = int(operator.truediv(dividend, divisor))
            if a >= 2**31 or a < -2**31:
                    return 2**31 - 1
    
            else:
                    return a
    
  • 相关阅读:
    【linux基础】usleep和sleep的区别
    【算法基础】opencv函数approxPolyDP和Ramer-Douglas-Peucker Algorithm
    【算法基础】散点轮廓算法-Alpha Shapes
    【图像处理算法基础】图像分割经典算法-泛洪算法FloodFill
    .net core 部署在Linux系统上运行的环境搭建
    Linux部署Net Core网站,三种自定义绑定端口号的方法(UseUrls,UseKestrel,手动指定)
    .NetCore部署Linux环境搭建
    .Net Core 项目发布到Linux
    .Net Core 项目发布到Linux
    Linux桌面操作系统排行榜
  • 原文地址:https://www.cnblogs.com/powercai/p/10805874.html
Copyright © 2011-2022 走看看