版权所有,欢迎转载,转载请注明出处,谢谢
Divide Two Integers
Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.
用减法做:超时。例如:(dividend, divisor) = (2147483647, 1)
方法一:利用二分法。
假设:要求的解在[a, b]中。(而本题中,解存在的范围为[0, dividend])
divisor * (a + b) / 2 > dividend => 解在[a, (a + b) / 2 - 1]中;
divisor * (a + b) / 2 == dividend => 解为(a + b) / 2;
divisor * (a + b) / 2 < dividend => 解在[(a + b) / 2 + 1, b]中或者解就是(a + b) / 2。
(因为不一定能够刚刚好整除,例如(dividend, divisor) = (5, 2),解为2)
求取(a + b) / 2可以用移位操作;
求取divisor * (a + b)/2 可以用二分加移位。
因此整个复杂度为O(logNlogN)。
P.S. 需要注意符号和数据越界。
//vs2012测试代码 #include<iostream> using namespace std; class Solution { private: long long multiplication(long long mid2, long long divisor2) { if (mid2 == 0) { return 0; } long long temp = multiplication(mid2 >> 1, divisor2) << 1; if ((mid2 & 1) != 0) { temp += divisor2; } return temp; } public: int divide(int dividend, int divisor) { int flag=1; long long ans=0; if(divisor == 0) return INT_MAX; if(dividend == 0) return 0; if( (dividend<0 && divisor>0) || (dividend>0 && divisor<0) ) { flag=-1; } long long dividend1 = abs((long long)dividend); long long divisor1 = abs((long long)divisor); long long left=0, right=dividend1, mid=-1; long long temp=0; while(left<=right) { mid = left + ((right-left)>>1); temp = multiplication( mid,divisor1); if(temp == dividend1) { ans = mid; break; } else if(temp>dividend1) right = mid - 1; else if(temp<dividend1) { ans = mid; left = mid + 1; } } ans = flag>0? ans : -ans; //着重考虑边界条件,容易忽略 if( ans > INT_MAX || ans < INT_MIN) return INT_MAX; return ans; } }; int main() { int dividend,divisor; cin>>dividend; cin>>divisor; Solution lin; cout<<lin.divide( dividend,divisor )<<endl; }
//方法一:自测Accepted class Solution { private: long long multiplication(long long mid2, long long divisor2) { if (mid2 == 0) { return 0; } long long temp = multiplication(mid2 >> 1, divisor2) << 1; if ((mid2 & 1) != 0) { temp += divisor2; } return temp; } public: int divide(int dividend, int divisor) { int flag=1; long long ans=0; if(divisor == 0) return INT_MAX; if(dividend == 0) return 0; if( (dividend<0 && divisor>0) || (dividend>0 && divisor<0) ) { flag=-1; } long long dividend1 = abs((long long)dividend); long long divisor1 = abs((long long)divisor); long long left=0, right=dividend1, mid=-1; long long temp=0; while(left<=right) { mid = left + ((right-left)>>1); temp = multiplication( mid,divisor1); if(temp == dividend1) { ans = mid; break; } else if(temp>dividend1) right = mid - 1; else if(temp<dividend1) { ans = mid; left = mid + 1; } } ans = flag>0? ans : -ans; //着重考虑边界条件,容易忽略 if( ans > INT_MAX || ans < INT_MIN) return INT_MAX; return ans; } };
//方法:超时 class Solution { public: int divide(int dividend, int divisor) { if(divisor == 0) return INT_MAX; else if(dividend == 0) return 0; else if(dividend>0 && divisor>0) { int count=0; while(1) { if(dividend < divisor) return count; else { dividend = dividend - divisor ; count++; } } } else if(dividend<0 && divisor<0) { dividend = -dividend; divisor = -divisor; int count=0; while(1) { if(dividend < divisor) return count; else { dividend = dividend - divisor ; count++; } } } else if(dividend>0 && divisor<0) { divisor = -divisor; int count=0; while(1) { if(dividend < divisor) return count; else { dividend = dividend - divisor ; count--; } } } else if(dividend<0 && divisor>0) { dividend = -dividend; int count=0; while(1) { if(dividend < divisor) return count; else { dividend = dividend - divisor ; count--; } } } } };
时间: 2024-10-14 17:09:30