前段时间由于放假、参加竞赛等等各种事情就中断了刷题的进程,现在已经开学回到学校,生活节奏也慢慢回到了正常的轨道上面,所以接下来应该还会坚持每天刷题的习惯。所以现在接着前面的进度继续进行binary-search部分接着做。
题目:
Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.
这道题目是在不使用乘、除、取模等运算的方法上实现除法。想到二插搜索一般我们会对数进行乘或者除2,那么该如何实现呢==当然是加法达到乘法的目的。还有一点需要注意的就是本题会涉及int数溢出的问题,而且两个数还可能是负数。所以要综合各种情况进行求解。
接下来说一下在不考虑溢出和负数的情况下如何使用binary-search实现除法。首先我们会考虑把除数逐渐翻倍直到大于被除数,然后接下来接着把被除数和翻倍之后的除数的差作为被除数继续递归即可。
下面给出两种方案,第一种是不使用binary-search,直接一次一次叠加的暴力法,但是这种会导致时间超时,另外一种就是binary-search。
public class divide {
public int divide(int dividend, int divisor) {
int sign = 1;
if((dividend > 0 && divisor < 0) || (dividend < 0 && divisor > 0))
sign = -1;
long ldividend = Math.abs((long)dividend);
long ldivisor = Math.abs((long)divisor);
if(ldivisor == 0)
return Integer.MAX_VALUE;
if((ldividend == 0) || (ldivisor > ldividend))
return 0;
long lans = ldivide1(ldividend, ldivisor);
int ans;
if(lans > Integer.MAX_VALUE)
ans = (sign == 1)? Integer.MAX_VALUE : Integer.MIN_VALUE;
else
ans = (int) (sign * lans);
return ans;
}
public long ldivide(long ldividend, long ldivisor){
if(ldividend < ldivisor)
return 0;
long sum = ldivisor;
long multiple = 1;
while(sum + sum <= ldividend){
sum += sum;
multiple += multiple;
}
return multiple + ldivide(ldividend - sum, ldivisor);
}
public long ldivide1(long ldividend, long ldivisor){
if(ldivisor == 1)
return ldividend;
long res = 0;
long tmp = ldivisor;
while(tmp <= ldividend){
tmp += ldivisor;
res += 1;
}
return res;
}
}