• 0029. Divide Two Integers (M)


    Divide Two Integers (M)

    题目

    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: ([−2^{31}, 2^{31} − 1]). For the purpose of this problem, assume that your function returns (2^{31} − 1) when the division result overflows.

    题意

    在不使用乘法、除法、取模操作的前提下,实现除法。若得到的商溢出Integer的范围,则返回Integer的最大值。

    思路

    首先要明确正负数除法的规则,经过实验可得Java的规则是使得到的商尽可能接近0(即直接省去得到的负数商的小数部分),说明商与除数的乘积的绝对值小于等于被除数的绝对值,在这个基础上实现除法的算法。

    最直接的做法是让被除数挨个减去(若正负数除法则为加上)除数,复杂度为(O(N))但在商的绝对值很大的情况下会超时。

    更高效方法的大致方向是:将除数和被除数都化为绝对值后,倍增除数,找到比被除数小的那个值,记录倍增的次数n,(2^n)即是所求的商,复杂度为(O(logN))。(当然具体实现更加复杂)

    因为题目要求环境只能存储int范围的值,所以不使用long,也不使用与乘除相似的位运算,具体操作直接看代码。


    代码实现

    Java

    class Solution {
        public int divide(int dividend, int divisor) {
            // 只有这一种情况会造成商溢出,先处理掉
            if (dividend == Integer.MIN_VALUE && divisor == -1) {
                return Integer.MAX_VALUE;
            }
    
            // 记录商的正负值
            boolean isMinus = ((dividend < 0) != (divisor < 0));
            
            // 如果除数或被除数中有一个是Integer.MIN_VALUE,那么取绝对值就会溢出
            // 所以全部转化为负数进行处理
            dividend = dividend > 0 ? -dividend : dividend;
            divisor = divisor > 0 ? -divisor : divisor;
    		
            // 如果被除数已经比除数大(因为全是负数),商只可能为0
            if (dividend > divisor) {
                return 0;
            }
    
            int quotient = 1;		// 商的绝对值
            int d = divisor;		// 当前需要在除数上累加的值
            int sum = divisor;		// 累加后的除数
            int count = 1;			// 当前累加值对应的divisor个数,d = count * divisor
    
            while (true) {
                // 当累加后的除数绝对值仍小于等于被除数时,则进行累加
                // sum + d < 0 的判断是为了防止sum+d后溢出
                if (sum + d < 0 && sum + d >= dividend) {
                    sum += d;				// 将待加值累加到除数上
                    d += d;					// 待加值自我累加
                    quotient += count;		// 更新商
                    count += count;			
                } else {
                    // 当且仅当加上待加值后的除数绝对值大于被除数,且待加值正好为最原始除数时才跳出
                    // 因为这时累加后的除数已经达到小于等于被除数的最大值,多加一个除数都不行
                    if (d == divisor) {
                        break;		
                    } else {
                        // 重置待加值,以尽可能使累加除数的绝对值接近被除数
                        d = divisor;
                        count = 1;
                    }
                }
            }
    		
            // 最后注意商的正负号
            return isMinus ? -quotient : quotient;
        }
    }
    

    JavaScript

    /**
     * @param {number} dividend
     * @param {number} divisor
     * @return {number}
     */
    var divide = function (dividend, divisor) {
      if (dividend === -Math.pow(2, 31) && divisor === -1) {
        return Math.pow(2, 31) - 1
      }
      let isMinus = dividend < 0 !== divisor < 0
      dividend = Math.abs(dividend)
      divisor = Math.abs(divisor)
      let quotient = 0
      let count = 1
      let curDiv = divisor
    
      while (dividend >= divisor) {
        if (dividend >= curDiv) {
          dividend -= curDiv
          quotient += count
          count += count
          curDiv += curDiv
        } else {
          curDiv = divisor
          count = 1
        }
      }
    
      return isMinus ? -quotient : quotient
    }
    

    ------------恢复内容结束------------

  • 相关阅读:
    QT自定义控件插件化简要概述
    wildfly9 配置SSL单向认证/https
    wildfly-9.0.2 web项目部署详细步骤
    SQL Server 2008 数据库日志文件丢失处理方法
    win7 64位系统 pl/sql 无法解析指定的连接标识符解决办法
    mybatis 应用参考
    去除浏览器下jquey easyui datagrid、combotree 缓存问题
    java 页面url传值中文乱码的解决方法
    jasperreports-5.6 + jaspersoftstudio-5.6 生成pdf 文件中文无法正常显示问题
    HTML5实现在线抓拍
  • 原文地址:https://www.cnblogs.com/mapoos/p/13185657.html
Copyright © 2020-2023  润新知