【算法百题之五十八】两数相除
大家好,我是Lampard~~
很高兴又能和大家见面了,接下来准备系列更新的是算法题,一日一练,早日升仙!
今天的问题是:两数相除
示例:
输入: dividend = 10, divisor = 3
输出: 3
解释: 10/3 = truncate(3.33333..) = truncate(3) = 3
输入: dividend = 7, divisor = -3
输出: -2
思路:从暴力法进行优化。题目要求我们不适用mod,乘法实现除法。其实我们可以想到,所有的乘除只不过是多次的加减而已,4 * 2 = 4 + 4, 4 * 3 = 4 + 4 + 4。我们只需要标记一下正负号以及取整即可。但是这样子做的话,肯定会超时,为了优化这个所发,我们可以每次按照倍数成倍的增长。
算法代码:
long divLoop(long a, long b) { // 似乎精髓和难点就在于下面这几句
if (a < b) return 0;
long count = 1;
long tb = b; // 在后面的代码中不更新b
while ((tb + tb) <= a) {
count = count + count; // 最小解翻倍
tb = tb + tb; // 当前测试的值也翻倍
}
return count + divLoop(a - tb, b);
}
int divide(int dividend, int divisor) {
if (dividend == 0) return 0;
if (divisor == 1) return dividend;
if (divisor == -1) {
if (dividend > INT_MIN) return -dividend; // 只要不是最小的那个整数,都是直接返回相反数就好啦
return INT_MAX; // 是最小的那个,那就返回最大的整数啦
}
long a = dividend;
long b = divisor;
int sign = 1;
if ((a > 0 && b < 0) || (a < 0 && b>0)) {
sign = -1;
}
a = a > 0 ? a : -a;
b = b > 0 ? b : -b;
long res = divLoop(a, b);
if (sign > 0) return res > INT_MAX ? INT_MAX : res;
return -res;
}
测试结果: