0%

29. 两数相除

29. 两数相除

1
2
3
4
5
6
7
8
9
越界问题只要对除数是1和-1单独讨论就完事了啊
关于如何提高效率快速逼近结果
举个例子:11 除以 3 。
首先11比3大,结果至少是1, 然后我让3翻倍,就是6,发现11比3翻倍后还要大,那么结果就至少是2了,那我让这个6再翻倍,得12,11不比12大,吓死我了,差点让就让刚才的最小解2也翻倍得到4了。但是我知道最终结果肯定在2和4之间。也就是说2再加上某个数,这个数是多少呢?我让11减去刚才最后一次的结果6,剩下5,我们计算5是3的几倍,也就是除法,看,递归出现了。说得很乱,不严谨,大家看个大概,然后自己在纸上画一画,或者直接看我代码就好啦!

作者:liujin-4
链接:https://leetcode-cn.com/problems/divide-two-integers/solution/po-su-de-xiang-fa-mei-you-wei-yun-suan-mei-you-yi-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
1
2
3
整理了一下思路,可以简单概括为: 60/8 = (60-32)/8 + 4 = (60-32-16)/8 + 2 + 4 = 1 + 2 + 4 = 7

leetcode@byMax(https://leetcode-cn.com/u/shellbye/)

溢出的情况只有负数最大除以-1会溢出,因为INT_MAX比INT_MIN绝对值小1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Solution {
public:
int divide(int dividend, int divisor) {
if(dividend == 0)
return 0;
if(divisor == 1)
return dividend;
if(divisor == -1)
return dividend == INT_MIN ? INT_MAX : -dividend;
int sign = 1;
if((dividend > 0 && divisor < 0) || (dividend < 0 && divisor > 0))
sign = -1;
long a = abs(dividend); // 转成long,防止溢出
long b = abs(divisor);
return sign * div(a, b);
}
private:
int div(long dividend, long divisor)
{
if(dividend < divisor)
return 0;
int c = 1;
long oriDivisor = divisor;
while(divisor + divisor < dividend)
{
c += c;
divisor += divisor;
}
return c + div(dividend - divisor, oriDivisor);
}
};