Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.
解题思路:
1. 通过被除数减去除数来得到被除数中包含多少个除数,一直减到被除数小于等于 0 则计算完成;
2. 如果是一个很大的被除数除以很小的除数,那么必然会超时(如 0x7FFFFFFF 除以 1 ,每次减 1 要减 20 亿次);
3. 为加速进行减法,每减一次除数,都将除数加倍,相应得本次除数包含的原始除数的个数是上一次除数包含的原始除数的个数的 2 倍;
4. 当被除数减到正好为零时,就正好得到结果;
5. 当被除数小于零时,判断当前的除数是否是原始的除数,如果是,那么说明被除数已经被减完,余下的部分已经不足以除以原始除数,所以直接返回结果;
6. 如果当前除数不是原始除数,那么说明除数剩余的本分还能够被原始除数除;
7. 在 6 步的情况下,求解新的被除数除以除数的问题和原始的问题是一个问题(问题规模减小了),所以此时可以进行递归求解(第一种方法),也可以非递归求解(第二种解法);
8. 问题还需要注意的地方有:
a. 若除数为 0 ,则直接返回无穷大((int)0x7FFFFFFF);
b. 若结果溢出,则返回相应的正的最大值((int)0x7FFFFFFF)或负的最大值((int)0x80000000);
完整代码:
递归解法:
#include
#include
#include
#include
#include
#include
using namespace std;
#define MAX_INT (int)0x7FFFFFFF
#define MIN_INT (int)0x80000000
class Solution {
public:
int divide(int dividend, int divisor) {
if(divisor == 0) return MAX_INT;
if(dividend == 0 ) return 0;
char f = '+';
if((dividend > 0 && divisor < 0) || (dividend <0 && divisor > 0))f = '-';
if(dividend < 0 && divisor < 0)f = '+';
long long dividendll = abs((long long)dividend);
long long divisorll = abs((long long)divisor);
long long count = func(dividendll,divisorll);
count = ((f == '+')?count:-count);
if(count > MAX_INT) count = MAX_INT;
if(count < MIN_INT) count = MIN_INT;
return count;
}
private:
long long func(long long dividendll, long long divisorll)
{
int time = 1;
int count = 0;
long long divisorBack = divisorll;
while(dividendll > 0){
dividendll -= divisorll;
if(dividendll > 0) count += time;
else if(dividendll == 0){
count += time;
return count;
}
else{
if(time == 1) return 0;
else break;
}
divisorll = divisorll << 1;
time = time << 1;
}
return count + func(dividendll+divisorll,divisorBack);
}
};
void main()
{
Solution s;
cout << s.divide(-2147483648,-1)<
非递归解法:
#include
#include
#include
#include
#include
#include
using namespace std;
#define MAX_INT (int)0x7FFFFFFF
#define MIN_INT (int)0x80000000
class Solution {
public:
int divide(int dividend, int divisor) {
if(divisor == 0) return MAX_INT;
if(dividend == 0 ) return 0;
char f = '+';
if((dividend > 0 && divisor < 0) || (dividend <0 && divisor > 0))f = '-';
if(dividend < 0 && divisor < 0)f = '+';
long long dividendll = abs((long long)dividend);
long long divisorll = abs((long long)divisor);
int time = 1;
long long count = 0;
while(dividendll > 0){
dividendll -= divisorll;
if(dividendll > 0){
count += time;
time = time << 1;
divisorll = divisorll << 1;
}
else if(dividendll == 0){
count += time;
break;
}
else{
if(time == 1) break;
else{
dividendll += divisorll;
divisorll = abs((long long)divisor);
time = 1;
}
}
}
count = ((f == '+')?count:-count);
if(count > MAX_INT) count = MAX_INT;
if(count < MIN_INT) count = MIN_INT;
return count;
}
};
void main()
{
Solution s;
cout << s.divide(-2147483648,-1)<