笔试题42. LeetCode OJ (29)

笔试题42. LeetCode OJ (29)_第1张图片

         题目意思清晰明了:求两个数的商,不能使用乘法,除法或者求模运算等等。看似很简单的一道题,可是在排行榜上的正确率却是最低的一道,原因是情况很复杂,边界很难控制。需要考虑到的细节特别多,如:正负号,除数和被除数的取值,还有就是越界情况。其中越界情况最难考虑到,我也给拉低这道题的正确率增加了一份”功劳“,真的测试了好几遍才将条件考虑全面,我的代码中写有很多注释(大部分以测试用例形式给出)可以帮助大家分析特定情况,这类型的题目没有很强的技巧,唯一需要注意的就是”细心“。对了,还有一个问题就是如何不使用乘除法以及求模运算求商。我的思路是采用移位运算(其实是一种特殊的乘法)举个例子吧: 

如 :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;
	}
};
代码中注释挺多的,希望不会让大家看的瞌睡来了,我的代码可能有点啰嗦,不过主要还是分细节去讨论了可能出现的情况。

笔试题42. LeetCode OJ (29)_第2张图片

你可能感兴趣的:(LeetCode,C++,算法)