Leetcode刷题(二十九)

两数相除(Medium)

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

整数除法应该向零截断,也就是截去(truncate)其小数部分。例如,8.345 将被截断为 8-2.7335 将被截断至 -2 。

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

注意:假设我们的环境只能存储 32 位 有符号整数,其数值范围是 [231,  2311] 。本题中,如果商 严格大于 2311 ,则返回 2311 ;如果商 严格小于 -231 ,则返回 -231 。

示例 1:

输入: dividend = 10, divisor = 3
输出: 3
解释: 10/3 = 3.33333.. ,向零截断后得到 3 。
示例 2:

输入: dividend = 7, divisor = -3
输出: -2
解释: 7/-3 = -2.33333.. ,向零截断后得到 -2 。
提示:

-231 <= dividend, divisor <= 231 - 1
divisor != 0
Related Topics
位运算
数学

思路分析

这道题要求不能使用乘法、除法以及余数来完成除法运算。我首先想到的是使用加减法,保留整数部分的除法可以看作是被除数减去整数个除数。我在根据这样的思路进行答题之后显示超时,这样计算对于比较大的数确实要花费大量的时间复杂度,这里就要使用一个方法叫做位移算法(也称为二进制除法)。位移算法通过将除数左移(即乘以2)来逼近被除数,这样可以更快地接近结果,从而提高效率。这种方法特别适用于处理大数除法,因为它减少了所需的迭代次数。
以下是使用位移算法实现整数除法的基本步骤:

处理符号:首先保存原始除数和被除数的符号,并使用它们的绝对值进行计算。
初始化:初始化一个变量来保存结果。
比较和位移:当被除数大于或等于除数时,不断地将除数左移(乘以2),直到它超过被除数。在每次位移时,也相应地位移一个用于计数的变量。
计算部分结果:将被除数减去最后一次位移后的除数,将结果加到最终结果中。
重复:重复以上步骤,直到被除数小于原始除数。
处理结果的符号:根据原始除数和被除数的符号,确定最终结果的符号。

使用位移来实现除法的原理基于二进制数的性质。在这种方法中,我们通过比较被除数与不断左移(即乘以2)的除数来逐步逼近最终的商。下面是详细的步骤和解释:

使用10除以3的例子,我们使用位移方法来求解:

  1. 初始化:将10和3都视为正数,因为它们已经是正数。商的初始值为0。

  2. 比较和逼近

    • 将除数3左移,直到它小于或等于被除数10。3左移1位变成6(小于10),3左移2位变成12(大于10),所以我们使用6(3左移1位)。
    • 从10中减去6,剩下4。由于我们左移了1位,这表示3的2倍,所以在商中加上2^1,即2。
  3. 处理剩余的部分

    • 现在处理剩下的4。3不能再左移,因为它会超过4。但是3本身小于4,所以我们可以从4中减去3,剩下1。
    • 在商中加上2的0次幂(因为我们没有左移),即加1。
  4. 最终结果

    • 到目前为止,我们已经从10中减去了6(3左移1位)和3,总共减去9,对应的商是2(对应6)加1(对应3),所以最终的商是3。

因此,10除以3的商是3,余数是1。使用位移方法进行的除法操作主要是逐步逼近被除数,直到无法再减去除数的任何倍数为止。

代码实现

//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
   
    public int divide(int dividend, int divisor) {
   
        // 处理溢出情况
        if (dividend == Integer.MIN_VALUE && divisor == -1) {
   
            return Integer.MAX_VALUE;
        }

        // 使用长整型防止溢出,并保存符号
        long longDividend = Math.abs((long)dividend);
        long longDivisor = Math.abs((long)divisor);
        boolean negative = (dividend < 0) ^ (divisor < 0);

        long result = 0;
        while (longDividend >= longDivisor) {
   
            long temp = longDivisor, multiple = 1;
            while (longDividend >= (temp << 1)) {
   
                temp <<= 1;
                multiple <<= 1;
            }
            longDividend -= temp;
            result += multiple;
        }

        return negative ? (int)-result : (int)result;
    }

}
//leetcode submit region end(Prohibit modification and deletion)

相关推荐

  1. Leetcode

    2024-01-25 07:40:04       35 阅读
  2. Leetcode四)

    2024-01-25 07:40:04       35 阅读
  3. Leetcode(三

    2024-01-25 07:40:04       37 阅读
  4. 每天一个数据分析

    2024-01-25 07:40:04       14 阅读
  5. Leetcode(三一)

    2024-01-25 07:40:04       30 阅读
  6. Leetcode(三三)

    2024-01-25 07:40:04       25 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-25 07:40:04       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-25 07:40:04       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-25 07:40:04       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-25 07:40:04       20 阅读

热门阅读

  1. toggle封装

    2024-01-25 07:40:04       35 阅读
  2. SpringBoot-SpringBoot自动配置底层源码解析

    2024-01-25 07:40:04       31 阅读
  3. 使用django-admin来做erp,是否需要使用缓存数据库

    2024-01-25 07:40:04       36 阅读
  4. 数据结构练习3

    2024-01-25 07:40:04       29 阅读
  5. 江苏服务器租用要注意哪些方面?

    2024-01-25 07:40:04       34 阅读
  6. html 粒子效果文字特效

    2024-01-25 07:40:04       35 阅读
  7. Hadoop-MapReduce-源码跟读-客户端篇

    2024-01-25 07:40:04       28 阅读
  8. CentOS 安装 Ruby

    2024-01-25 07:40:04       41 阅读
  9. VSCode Python调试运行:json编写

    2024-01-25 07:40:04       30 阅读