Divide Two Integers
Description
Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.
Tags: Math, Binary Search
思路
题意是让你算两个整型数相除后的结果,如果结果溢出就返回 MAX_INT
,但不能使用乘、除、余的操作符,如果是用加减操作符的话肯定会超时哈,这样的话我们就只能想到位操作符了。
首先,我们分析下溢出的情况,也就是当被除数为 Integer.MIN_VALUE
,除数为 -1
时会溢出,因为 |Integer.MIN_VALUE| = Integer.MAX_VALUE + 1
。
然后,我们把除数和被除数都转为 long
类型的正数去做下一步操作,我这里以 22
和 3
相除为例子,因为 22 >= 3
,我们对 3
进行左移一位,也就是乘 2,结果为 6
,比 22
小,我们继续对 6
左移一位结果为 12
,还是比 22
小,我们继续对 12
左移一位为 24
,比 22
大,这时我们可以分析出,22
肯定比 3
的 4
倍要大,4
是怎么来的?因为我们左移了两次,也就是 1 << 2 = 4
,此时我们记下这个 4
,然后让 22 - 3 * 4 = 10
,因为 10 >= 3
,对 10
和 3
进行同样的操作,我们可以得到 2
,此时加上上次的 4
,和为 6
,也就是 22
比 3
的 6
倍要大,此时还剩余 10 - 6 = 4
,因为 4 >= 3
,所以对 4
和 3
进行同样的操作,我们发现并不能对 3
进行左移了,因为 4 >= 3
,所以 1
倍还是有的,所以加上最后的 1
,结果为 6 + 1 = 7
,也就是 22
整除 3
结果为 7
。
最终,我们对结果赋予符号位即可,根据以上思路来书写如下代码应该不是难事了吧。
class Solution {
public int divide(int dividend, int divisor) {
if (dividend == Integer.MIN_VALUE && divisor == -1) {
return Integer.MAX_VALUE;
}
long dvd = Math.abs((long) dividend);
long dvr = Math.abs((long) divisor);
int res = 0;
while (dvd >= dvr) {
long temp = dvr, multiple = 1;
while (dvd >= temp << 1) {
temp <<= 1;
multiple <<= 1;
}
dvd -= temp;
res += multiple;
}
return (dividend < 0) ^ (divisor < 0) ? -res : res;
}
}
结语
如果你同我们一样热爱数据结构、算法、LeetCode,可以关注我们 GitHub 上的 LeetCode 题解:LeetCode-Solution