两数相除(Medium)
给你两个整数,被除数 dividend 和除数 divisor。将两数相除,要求 不使用 乘法、除法和取余运算。整数除法应该向零截断,也就是截去(truncate)其小数部分。例如,8.345 将被截断为 8 ,-2.7335 将被截断至 -2 。返回被除数 dividend 除以除数 divisor 得到的 商 。注意:假设我们的环境只能存储 32 位 有符号整数,其数值范围是 [−231, 231 − 1] 。本题中,如果商 严格大于 231 − 1 ,则返回 231 − 1 ;如果商 严格小于 -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的例子,我们使用位移方法来求解:
-
初始化:将10和3都视为正数,因为它们已经是正数。商的初始值为0。
-
比较和逼近:
- 将除数3左移,直到它小于或等于被除数10。3左移1位变成6(小于10),3左移2位变成12(大于10),所以我们使用6(3左移1位)。
- 从10中减去6,剩下4。由于我们左移了1位,这表示3的2倍,所以在商中加上2^1,即2。
-
处理剩余的部分:
- 现在处理剩下的4。3不能再左移,因为它会超过4。但是3本身小于4,所以我们可以从4中减去3,剩下1。
- 在商中加上2的0次幂(因为我们没有左移),即加1。
-
最终结果:
- 到目前为止,我们已经从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)