Divide Two Integers
Divide two integers without using multiplication, division and mod operator.
不用* 、/、%来做除法。只能加减了啊亲!
算法思路:
一个一个加上去必超时,例如dividend = Integer.MAX_VALUE,divisor = 1;因此这是不行滴。
思路1:比O(n)还高效的,就是二分法了;
【注意】处理溢出、处理负数情况、处理0的情况;
divisor每次翻一番,当翻到比dividend大的时候,记录增长的倍数。更新dividend,再从divisor开始增长。
例如12 / 1,1->2->4->8->16 (16 > 12)则回到将dividend更新为12- 8= 4。然后divisior再从1开始增长 1 ->2->4结束。
代码如下:
public class Solution { public int divide(int dividend, int divisor) { if(dividend == 0 || divisor == 0) return 0; long absDividend = Math.abs((long) dividend); long absDivisor = Math.abs((long) divisor); if(absDividend < absDivisor) return 0; int res = 0; while(absDividend >= absDivisor){ long count = 1; long tem = absDivisor; while(tem < absDividend){ tem <<= 1; count <<= 1; } if(tem != absDivisor) { tem >>= 1; count >>= 1; } res += count; absDividend -= tem; }//这个异或用很不错 return res * (dividend < 0 ^ divisor < 0 ? (-1) : 1); } }
思路2:
维护一个一维数组multi,multi[i]存储除数扩大i倍的情况,然后用被除数减。具体请参考这里。
public class Solution { public int divide(int dividend, int divisor) { if (dividend == 0 || divisor == 1) return dividend; long divid = dividend; long divis = divisor; boolean neg = false;//经典负数处理 int result = 0; if (dividend < 0) { neg = !neg; divid = -divid; } if (divisor < 0) { neg = !neg; divis = -divis; } long[] multi = new long[32]; for (int i = 0; i < 32; i++) multi[i] = divis << i; for (int i = 31; i >= 0; i--) { if (divid >= multi[i]) { result += 1 << i; divid -= multi[i]; } } return (neg ? -1 : 1) * result; }
参考资料:
http://www.cnblogs.com/jdflyfly/p/3810717.html