问题链接
LeetCode 29. Divide Two Integers
Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.
题目解析
两数相除,不得使用乘法、除法、取模运算。
解题思路
题目限制这么大,很明显是要考察专一的知识点,那是什么呢?神奇的 位运算操作,简单来讲就是 二进制 的运用。
你最初的思路可能是这样子,只运用减法,每次减去除数,最后总能得到结果,没错,但是这样有什么意义呢?我觉得应该可以AC,但也不想去试着写这样的辣鸡代码。一个一个减,多想一下,可不可以多个一起减呢?
举一个简单的例子,求解40÷3,结果为13(忽略余数),如果一个一个减,在第14次减去3的时候可以知道答案是13。这个13可以可以以另一种方式得到,每一个数都有二进制表示,它的含义是什么呢,其实是多个2的幂值相加,这里的13=8+4+1,意味着40=(8*3)+(4*3)+(1*3)···1,所以问题转化为求这多个2的幂值。
具体实现,最初的想法是每次循环减一次(1*除数),现在改进后,每次循环减去(最大2的幂值*除数),通过左移运算,每次将幂值<<1(乘2),求得最大2的幂值后,更新被除数和结果。如何求得最大2的幂值,可参考代码理解。
注意:排除特殊情况,除数为0或者超出int范围。左移运算中,数值范围可能超出int,采用long或者long long都可以。
参考代码
class Solution {
public:
int divide(int dividend, int divisor) {
if (!divisor || (dividend == INT_MIN && divisor == -1)) return INT_MAX;
int sign = ((dividend < 0) ^ (divisor < 0)) ? -1 : 1;
long long dvd = labs(dividend);
long long dvs = labs(divisor);
int res = 0;
while (dvd >= dvs) {
long long temp = dvs, multiple = 1;
while (dvd >= (temp << 1)) {
temp <<= 1;
multiple <<= 1;
}
dvd -= temp;
res += multiple;
}
return sign == 1 ? res : -res;
}
};
参考链接:Detailed Explained 8ms C++ solution
LeetCode All in One题解汇总(持续更新中...)
本文版权归作者AlvinZH和博客园所有,欢迎转载和商用,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.