29. 两数相除
给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。
返回被除数 dividend 除以除数 divisor 得到的商。
整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2
解题思路
我只能说 要考虑类型溢出的题是真的噩梦 每次都要错几回
没什么好说的思路 就是用除数每次 *2 一直到结果大于被除数 然后再用 (被除数-当前方法中的商) 作为被除数进行递归 结束判断是被除数小于除数
重点在于:
- 该递归方法只适用于两个正数 所以我们要将两个数化为正数
- 一开始我根本没想到用long来存int 一直在想怎么让 int * -1 之后不溢出 (结果确实是没想出来)
- 用到了long之后 又出了个问题 我用的是Math.abs() 来取绝对值 但tm以前没出现过这么大的数, 根本没想到它返回的就是int 然后错了
最后: 吃一堑长一智 希望下次再碰到溢出的时候 不会再错了
public static int divide(int dividend, int divisor) {
int flag = (dividend > 0 && divisor > 0) || (dividend < 0 && divisor < 0) ? 1 : -1;
if(divisor == 1){
return dividend;
}
if(divisor == -1){
if(dividend>Integer.MIN_VALUE) return -dividend;
return Integer.MAX_VALUE;
}
long a = dividend>0?dividend:dividend*-1L;
long b = divisor>0?divisor:divisor*-1L;
return flag*getQuotient(a,b);
}
public static int getQuotient(long dividend,long divisor){
if (dividend < divisor) {
return 0;
}
int quotient = 1;
while (divisor * quotient * 2 < dividend) {
quotient *= 2;
}
return quotient + getQuotient(dividend-quotient*divisor,divisor);
}