mirror of
https://github.com/ShusenTang/LeetCode.git
synced 2024-09-02 14:20:01 +00:00
Update 29. Divide Two Integers.md
This commit is contained in:
parent
247f249042
commit
7ae5369958
@ -6,12 +6,19 @@
|
|||||||
假设除数和被除数都是正数,例如考虑15除3,先用15-3发现结果等于12>3,再尝试用15-6发现结果得9>3,再尝试用15-12发现结果3=3,再尝试用15减去24发现不够减,
|
假设除数和被除数都是正数,例如考虑15除3,先用15-3发现结果等于12>3,再尝试用15-6发现结果得9>3,再尝试用15-12发现结果3=3,再尝试用15减去24发现不够减,
|
||||||
则应该用15-12然后余3,此时商得4;然后再考虑3除3,依然用上面的思路,得到商为1,最终的结果就是将每一步得到的商相加即可。
|
则应该用15-12然后余3,此时商得4;然后再考虑3除3,依然用上面的思路,得到商为1,最终的结果就是将每一步得到的商相加即可。
|
||||||
如果是负数的话先取绝对值最后判断符号即可。
|
如果是负数的话先取绝对值最后判断符号即可。
|
||||||
另外需要考虑两个溢出的情况:
|
|
||||||
* `dividend == INT_MIN && divisor == -1`,结果是`-INT_MIN`超出了int的表示范围。
|
|
||||||
* ·dividend == INT_MIN && divisor == 1`,结果是`INT_MIN`虽然没有超过范围,但是我们是按照绝对值计算结果的,所以计算过程res也会溢出。
|
|
||||||
|
|
||||||
另外需要注意的是再用abs(x)求绝对值的时候一定要先将x转换成long long型这样abs(x)返回的才是long long型,保证不溢出。否则若x=INT_MIN的话求绝对值就超过
|
需要考虑唯一溢出的情况:
|
||||||
int型表示范围了。
|
* `dividend == INT_MIN && divisor == -1`,结果是`-INT_MIN`超出了int的表示范围。
|
||||||
|
|
||||||
|
还需要考虑一些特殊情况:
|
||||||
|
* `dividend == 0`,直接返回0即可;
|
||||||
|
* `divisor == 1`,直接返回`dividend`,因为我们是按照绝对值计算res的,所以这样可以避免当`dividend=INT_MAX`中间结果溢出。
|
||||||
|
|
||||||
|
另外需要注意的是再用abs(x)求绝对值的时候要考虑x是否是INT_MIN。
|
||||||
|
1. 对于`divisor == INT_MIN`,可以直接得到res为1或0,直接返回即可;
|
||||||
|
2. 而对于`dividend`,我们可以求`abs(dividend) - 1`来避免溢出,最后加上这个1即可。
|
||||||
|
|
||||||
|
> 也可以先将x转换成long long型,这样abs(x)返回的是long long型,保证不溢出。
|
||||||
|
|
||||||
[参考](https://leetcode.com/problems/divide-two-integers/discuss/13407/Detailed-Explained-8ms-C%2B%2B-solution)
|
[参考](https://leetcode.com/problems/divide-two-integers/discuss/13407/Detailed-Explained-8ms-C%2B%2B-solution)
|
||||||
|
|
||||||
@ -21,27 +28,32 @@ class Solution {
|
|||||||
public:
|
public:
|
||||||
int divide(int dividend, int divisor) {
|
int divide(int dividend, int divisor) {
|
||||||
if(dividend == 0) return 0;
|
if(dividend == 0) return 0;
|
||||||
if(dividend == INT_MIN && divisor == -1) return INT_MAX;
|
if(dividend == INT_MIN && divisor == -1) return INT_MAX; // 唯一可能的溢出情况
|
||||||
if(dividend == INT_MIN && divisor == 1) return INT_MIN;
|
if(divisor == 1) return dividend;
|
||||||
int res = 0;
|
|
||||||
long long dvd = abs((long long)dividend); // 一定要先将dividend和divisor转换成long long型这样abs才返回long long型
|
|
||||||
long long dvs = abs((long long)divisor);
|
|
||||||
long long dvs_bk = dvs; // 除数备份
|
|
||||||
|
|
||||||
while(dvd >= dvs){
|
if(divisor == INT_MIN) return dividend == INT_MIN ? 1 : 0;
|
||||||
int curr = 1;
|
|
||||||
dvs <<= 1;
|
int abs_dividend_minus_1 = abs(dividend + (dividend < 0 ? 1: -1));
|
||||||
while(dvd - dvs >= 0){
|
|
||||||
curr *= 2;
|
int abs_divisor = abs(divisor), step = abs(divisor), step_i= 1;
|
||||||
dvs <<= 1;
|
int res = 0;
|
||||||
} // dvd < dvs
|
while(abs_dividend_minus_1 >= abs_divisor){
|
||||||
dvs >>= 1;
|
while(abs_dividend_minus_1 < step){
|
||||||
dvd -= dvs;
|
step >>= 1;
|
||||||
dvs = dvs_bk;
|
step_i >>= 1;
|
||||||
res += curr;
|
|
||||||
}
|
}
|
||||||
if(dividend > 0 && divisor < 0) res *= -1;
|
abs_dividend_minus_1 -= step;
|
||||||
else if(dividend < 0 && divisor > 0) res *= -1;
|
res += step_i;
|
||||||
|
|
||||||
|
if(step <= (INT_MAX >> 1)){
|
||||||
|
step <<= 1;
|
||||||
|
step_i <<= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(abs_dividend_minus_1 + 1 == abs_divisor) res += 1;
|
||||||
|
|
||||||
|
if((dividend > 0 && divisor < 0) || (dividend < 0 && divisor > 0)) return -res;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user