给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。
返回被除数 dividend 除以除数 divisor 得到的商。
整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335)
= -2
leetcode
解题思路:
- 因为这里只需要求整数部分,首先能够想到的是拿除数去循环减被除数,能减多少个还是非负数,答案就是多少,这样的效率很低,如果被除数特别大,除数特别小,就会导致超时。
- 这里可以用到快速幂的思想,因为答案是一个32位的整型,所以,从最高位开始枚举,第i位对应的值就是
num << i
,如果被除数大于该值,则减,表示除去了相应个数的除数,同时答案增加该位的数值1 << i
。
class Solution {
public int divide(int dividend, int divisor) {
if(dividend == 0) return 0;
// 特判,这个用例有毛病
if(dividend == Integer.MIN_VALUE && divisor == -1) return Integer.MAX_VALUE;
// 排除负数
boolean isMin = false;
if(dividend < 0 && divisor > 0 || dividend > 0 && divisor < 0) isMin = true;
long nd = Math.abs((long) dividend);
long ns = Math.abs((long) divisor);
int res = 0;
// 从高位开始枚举,每一位是否可以减去答案
for(int i = 31; i >= 0; i--) {
// 判断该位是否存在数值
if((ns << i) <= nd) {
res += 1 << i;
nd -= ns << i;
}
}
return isMin ? -res : res;
}
}