深圳模板网站建设哪家好软文推广的优点
ps:题目来自力扣
两数相除
给你两个整数,被除数 dividend
和除数 divisor
。将两数相除,要求 不使用 乘法、除法和取余运算。
整数除法应该向零截断,也就是截去(truncate
)其小数部分。例如,8.345
将被截断为 8
,-2.7335
将被截断至 -2
。
返回被除数 dividend
除以除数 divisor
得到的 商 。
注意:假设我们的环境只能存储 32 位 有符号整数,其数值范围是 [−231, 231 − 1]
。本题中,如果商 严格大于 231 − 1
,则返回 231 − 1
;如果商 严格小于 -231
,则返回 -231
。
class Solution {public int divide(int dividend, int divisor) {// 处理边界情况,当被除数为最小值且除数为 -1 时,结果会超出 32 位有符号整数范围,直接返回最大值if (dividend == Integer.MIN_VALUE && divisor == -1) {return Integer.MAX_VALUE;}// 判断结果的符号,通过异或运算判断两数符号是否不同boolean negative = (dividend ^ divisor) < 0;// 将被除数和除数都转换为负数,因为负数的范围更大,能避免溢出问题dividend = -Math.abs(dividend);divisor = -Math.abs(divisor);int result = 0;while (dividend <= divisor) {int tempDivisor = divisor;int multiple = 1;// 不断将除数翻倍,同时倍数也翻倍,直到翻倍后的除数大于当前被除数while (dividend - tempDivisor <= tempDivisor) {tempDivisor <<= 1;multiple <<= 1;}// 减去当前能减去的最大的除数倍数dividend -= tempDivisor;// 累加对应的倍数到结果中result += multiple;}// 根据之前判断的符号,决定结果的正负return negative ? -result : result;}
}
代码解释
本题要求在不使用乘法、除法和取余运算的情况下,计算两个整数的商,并且要考虑 32 位有符号整数的范围。我们可以采用减法和位运算的方法来模拟除法。
具体步骤
- 处理边界情况:
- 当被除数为
Integer.MIN_VALUE
且除数为 -1 时,商为Integer.MAX_VALUE + 1
,会超出 32 位有符号整数的范围,所以直接返回Integer.MAX_VALUE
。
- 当被除数为
- 判断结果的符号:
- 通过异或运算
(dividend ^ divisor) < 0
判断被除数和除数的符号是否不同,如果不同则结果为负。
- 通过异或运算
- 将被除数和除数转换为负数:
- 为了避免溢出问题,将被除数和除数都转换为负数,因为负数的范围比正数大。
- 模拟除法过程:
- 使用
while
循环,只要被除数小于等于除数,就继续进行除法操作。 - 在每次循环中:
- 初始化临时除数
tempDivisor
为除数,倍数multiple
为 1。 - 不断将
tempDivisor
翻倍,同时multiple
也翻倍,直到tempDivisor
大于当前被除数。 - 用被除数减去
tempDivisor
,并将multiple
累加到结果result
中。
- 初始化临时除数
- 使用
- 根据符号返回结果:
- 根据之前判断的符号,决定最终结果的正负,如果为负则返回
-result
,否则返回result
。
- 根据之前判断的符号,决定最终结果的正负,如果为负则返回