LeetCode29. 两数相除
给定两个整数,被除数 dividend
和除数 divisor
。将两数相除,要求不使用乘法、除法和 mod 运算符。
返回被除数 dividend
除以除数 divisor
得到的商。
整数除法的结果应当截去(truncate
)其小数部分,例如:truncate(8.345) = 8
以及 truncate(-2.7335) = -2
示例 1:
输入: dividend = 10, divisor = 3
输出: 3
解释: 10/3 = truncate(3.33333..) = truncate(3) = 3
示例 2:
输入: dividend = 7, divisor = -3
输出: -2
解释: 7/-3 = truncate(-2.33333..) = -2
提示:
- 被除数和除数均为 32 位有符号整数。
- 除数不为 0。
- 假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231 − 1]。本题中,如果除法结果溢出,则返回 231 − 1。
题解:
该题禁止我们使用乘法,除法或者是mod运算符,那么我们首先想到的就是使用位运算符进行求解:
- 但是其中需要对于最大值和最小值为被除数或者除数的情况,进行多方面的讨论
class Solution {
/*
* dividend 被除数
* divisor 除数
* */
public int divide(int dividend, int divisor) {
//如果被除数为0,则直接返回0
if (dividend == 0) return 0;
//如果除数为1,则直接返回被除数
if (divisor == 1) return dividend;
//如果被除数是最小值,并且除数为-1,则返回最大值【因为java中int类型的最大值为2^31 - 1,最小值为-2^31】
if (dividend == Integer.MIN_VALUE) {
if (divisor == -1) {
return Integer.MAX_VALUE;
}
}
//如果除数为最小值
if (divisor == Integer.MIN_VALUE) {
//被除数为最小值,结果为1
if (dividend == Integer.MIN_VALUE) {
return 1;
}else {
//否则直接返回0
return 0;
}
}
//对于上述的特殊情况,我们进行了单独的判断以后,此时为了不越界,我们使用long类型去接x和y
long x = dividend;
long y = divisor;
int flag = 1; //记录结果的正负
if ((x > 0 && y < 0) || (x < 0 && y > 0)) {
flag = -1;
}
x = x > 0 ? x : -x;
y = y > 0 ? y : -y;
//通过div方法求解x / y的值
long res = div(x,y);
return flag * (int)res;
}
//不使用乘法,除法以及mod运算符进行x / y操作的方法:使用左移位运算实现
private long div(long x, long y) {
//如果x 小于 y,则直接返回0
if (x < y) {
return 0;
}
long cnt = 1;
//定义一个temp变量,等于y的值
long temp = y;
//使用左移1位完成乘以2的操作...
while ((temp << 1) <= x) {
cnt = cnt << 1;
temp = temp << 1;
}
return cnt + div(x - temp,y);
}
}