使用移位运算和加减法实现乘除法

这个想法是在做leetcode 的题目29 Divide Two Integers时产生的,原题描述如下:

Divide two integers without using multiplication, division and mod operator.

If it is overflow, return MAX_INT.

就是说不用乘除取余运算来实现两个int醒变量的整除,然后如果溢出的话就返回INT_MAX

先把问题简化一下,不考虑溢出问题,并且假设被除数n大于除数m大于0,嗯,基于这个假设,剩下的就是纯粹的算法部分了。说到整除问题,有n/m==k+r(r==n mod m),也就是我们小学学过的被除数除以除数等于商加余数。根据这个公式很自然的想到用n逐次减去m直到差小于m,代码如下;

int i=0;
while (n>=m) 
{
	n-=m;
	i++;
return i;

如果n和m比较接近的话,这样做还是很快的,但是对于一般情况,其时间复杂度为O(n/m),有些捉急,尤其是n特别大而m又很小的时候,简直不能忍,按这种思路提交的算法会提示超时(意料之中)。那么有没有别的方法呢?显然有!答案就是位运算。

使用左移和右移可以很方便地实现乘除2^的n次方,而 n/m==k+r 即 m*k==n-r 即 m*(2^l1+2^l2+……+2^ls)==n-r ,即m<

int k=0,i=o;
while (n>=m)
        {
            if (n>=m< 
  

这样一来,一般情况下的时间复杂度大大降低,只有O(k的二进制表示的位数)。

同理,整数乘法也可以用位运算来实现。

int i=0,k=0;
while (m)
{
	if (m>=1<	{
		k+=n<		m-=1<		i++;
	}
	else
	{
		i=0;
	}
}

以上就是我能想到的方法,然后具体到这个题目的话,还要考虑除数为0以及溢出问题,比如被除数为-2^31时该怎么解决。


你可能感兴趣的:(leetcode,移位运算)