1. 题目描述:
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.
2. 思路分析:
题目的意思是在不使用乘法,除法和取模操作的情况下实现整数的除法运算,整型溢出则返回最大整型。
既然不能用乘、除、取模,只能用移位操作来完成了。将除数 divisor
每次左移一位,找到最接近被除数且不大于被除数 dividend
的一个数,然后将被除数减去这个数,继续之前的操作。例如:31除以3,将3不断左移,直到左移3位后达到最接近31且不大于31的数,即3*2*2*2=24(此时相当于将3乘以了8,这个8是结果的一部分),然后将31-24=7,继续之前的操作,左移3,直到最接近7且不大于7的一个数,即将3左移一位得到3*2=6(这个2也是结果的一部分),然后7-6=1,继续之前的操作,因为3已经大于1了,所以不需要左移了,即得到最后的结果为:8+2=10
3. Java代码:
源代码
:见我GiHub主页
代码:
public static int divide(int dividend, int divisor) {
if (divisor == 0) {
return Integer.MAX_VALUE;
}
// 用long型来存储,防止越界
long dividendLong = dividend;
long divisorLong = divisor;
long dividendAbs = Math.abs(dividendLong);
long divisorAbs = Math.abs(divisorLong);
if (dividendAbs < divisorAbs) {
return 0;
}
long tempResult = 1;
long m = dividendAbs;
long n = divisorAbs;
// 通过移位找到最大的乘数,使得和 n 的乘积小于等于 m
while ((m >> 1) >= n) {
tempResult = tempResult << 1;
n = n << 1;
}
// 递归求解
long result = tempResult + divide((int)(m - n), (int)divisorAbs);
// 确定最后结果的符号,及是否越界
if ((dividend > 0 && divisor < 0) || (dividend < 0 && divisor > 0)) {
return -result < Integer.MIN_VALUE ? Integer.MIN_VALUE : (int)-result;
} else {
return result > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)result;
}
}