題目意思清晰明了:求兩個數的商,不能使用乘法,除法或者求模運算等等。看似很簡單的一道題,可是在排行榜上的正確率卻是最低的一道,原因是情況很復雜,邊界很難控制。需要考慮到的細節特別多,如:正負號,除數和被除數的取值,還有就是越界情況。其中越界情況最難考慮到,我也給拉低這道題的正確率增加了一份”功勞“,真的測試了好幾遍才將條件考慮全面,我的代碼中寫有很多注釋(大部分以測試用例形式給出)可以幫助大家分析特定情況,這類型的題目沒有很強的技巧,唯一需要注意的就是”細心“。對了,還有一個問題就是如何不使用乘除法以及求模運算求商。我的思路是采用移位運算(其實是一種特殊的乘法)舉個例子吧:
如 :23/4
(4<<3)= 32 > 23
(4<<2)=16 < 23
那麼商在 2^2(4)~2^3(8)之間,最小為 4(第一部分)
23-4*2^2 = 23 - 16 = 7
4<<1 = 8 > 7 , 但是 4 < 7 所以可以求出第二部分的商為 1
綜上所述,23/4 = 5(商為5)
如果還不理解那就參看我的代碼吧,代碼如下:
class Solution { public: int divide(int dividend, int divisor) { //求兩個數的商 //1.被除數為0 if (divisor == 0) {//不合法的數 return 0; } //2.除數為 0 if (dividend == 0) {//除數為0 return 0; } //3.被除數為1 if (divisor == 1) { return dividend; } //4.被除數為2 else if (divisor == 2) { return dividend >> 1; } //5.考慮溢出問題,正數溢出或者負數溢出 double maxint = pow(2, 31) - 1; if (dividend - maxint > 0.000001) { dividend = int(maxint); } if (divisor - maxint > 0.000001) { divisor = int(maxint); } if(dividend < maxint*(-1) && divisor < maxint*(-1)) {// 例如:-2147483648 / -2147483648 return 1; } if (dividend < maxint*(-1)) { dividend = maxint*(-1); } if (divisor < maxint*(-1)) {//被除數越界 例如:(1~2147483647) / -2147483648 //divisor = maxint*(-1); return 0; } //6.考慮正負號 int minus = 1; //商是否為負數 if (dividend < 0 && divisor < 0) { dividend *= -1; divisor *= -1; if (divisor > dividend) { return 0; } } else { if (dividend < 0) { dividend *= -1; minus = -1; } if (divisor < 0) { divisor *= -1; minus = -1; } } if (dividend == divisor) { //例如: 1 / -1 return 1*minus; } //7.被除數為1 if (divisor == 1) { //例如: -1 / -1 return dividend; } else if (divisor == 2) { //例如: -6 / -2 return dividend >> 1; } //8.開始求商 25 / 4 -> 6 4<<2--16 25 4<<3--32 所以,商在4~8之間 int left = 0; int right = 1; int ret = 0; int mybeover = maxint / 2; while (dividend > divisor) { left = 0; right = 1; while ((divisor << right) < dividend) { if ((divisor << left) >= mybeover) { break; } ++left; ++right; } ret += 1 << left; dividend -= divisor << left; } return ret*minus; } };代碼中注釋挺多的,希望不會讓大家看的瞌睡來了,我的代碼可能有點啰嗦,不過主要還是分細節去討論了可能出現的情況。