题目链接:Divide Two Integers
Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.
这道题的要求是在不使用乘法、除法、取模运算的前提下实现两个整数相除。如果溢出,返回MAX_INT。
这道题的直接思路是用被除数不断减去除数,直到为0。这种方法的迭代次数是结果的大小,即比如结果为n,算法复杂度是O(n)。
可以采用位运算进行优化,即模拟计算机上的除法运算。将整数转化成二进制形式,即num = a0*2^0 + a1*2^1 + a2*2^2 + ... + an*2^n。基于以上这个公式以及左移一位相当于乘以2,可以先让除数左移直到大于被除数之前得到一个最大的基数。然后每次用被除数去减去这个基数,同时结果增加2^k。接下来继续重新左移除数左移迭代,直到被除数不大于除数为止。因为这个方法的迭代次数是按2的幂直到结束,所以时间复杂度为O(logn)。
值得注意的地方,主要就是处理符号和溢出问题。对于溢出问题,可以先采用long long进行计算,也可以在移位前判断移位后是否溢出。
时间复杂度:O(logn)
空间复杂度:O(1)
1 class Solution
2 {
3 public:
4 int divide(int dividend, int divisor)
5 {
6 int sign = (dividend < 0) ^ (divisor < 0) ? - 1 : 1;
7 long long res = 0, m = abs((long long)dividend), n = abs((long long)divisor);
8 while(m >= n)
9 {
10 long long t = n, i = 1;
11 while(t << 1 < m)
12 {
13 t <<= 1;
14 i <<= 1;
15 }
16 m -= t;
17 res += i;
18 }
19 if(sign < 0)
20 res = -res;
21 return res > INT_MAX ? INT_MAX : res;
22 }
23 };