Divide Two Integers

题目 : Divide two integers without using multiplication, division and mod operator. If it is overflow, return MAX_INT.

我们不实用除法进行整数除法运算,如果溢出的话,我们就返回整形的最大值。

1、我们第一想到的是直接相减(a, b),被除数不断的减去除数看最多能减几次,就返回。

然而很容易TLE.

public class Solution {
    public int divide(int dividend, int divisor) {
        long count = 0;
        if(divisor == 0){
           return Integer.MAX_VALUE; 
        }
        int ret = 1;
        if((dividend < 0 && divisor > 0)||(dividend > 0 && divisor < 0)){
            ret = -1;
        }
        long divid = dividend;
        divid = Math.abs(divid);
        long divis = divisor;
        divis = Math.abs(divis);
        while(divid >= divis) {
            divid = divid - divis;
            count ++;
        }
        if(ret * count > Integer.MAX_VALUE || ret * count < Integer.MIN_VALUE){
            return Integer.MAX_VALUE;
        }
        return (int)(ret * count);
    }
}


2、于是我们想能不能通过为运算进行操作呢例如(15,4),向右移一位的话,意味着缩小二倍,我们就不断的缩小,直到被除数刚好小于除数。

即最多只能右移一位 ,此刻 15 - 2 * 4 = 7 ,然后对 7又进行上述的操作,7不能右移 所以 最后 7 - 4  = 3 此刻 总共减去4的次数是 3 ,代码如下



public class Solution {
     public  int divide(int dividend, int divisor) {
		  if(divisor == 0){
			  return Integer.MAX_VALUE;
		  }
		  int ret = -1;
		  if(((dividend>>31)^(divisor >> 31)) == 0){
	           ret = 1;
	      }
		  long divid = dividend;
		  long divis = divisor;
		  long result = helpDivide(Math.abs(divid),Math.abs(divis));
		  if(result > Integer.MAX_VALUE && ret == 1){
			  return Integer.MAX_VALUE;
		  }
	      return ret * (int)result;
	 }
	 public long helpDivide(long dividend, long divisor){
		 if(dividend < divisor){
			 return 0;
		 }else{
			 long sub = 0;
			 int i = 1;
			 int count = 0;
			 for(;i < 32 ;i++){
		    	  if((dividend >> i) < divisor){
		    		  break;
		    	  }
		    	  count ++;
		      }
		      sub = dividend - (long)(Math.pow(2,count)*divisor);
		      return (long)Math.pow(2,count)+helpDivide(sub,divisor);
		 }
	 }
}

我们对他进行优化,此刻超过了89%   36ms Java:

public class Solution {
     public  int divide(int dividend, int divisor) {
 if(divisor == 0){
 return Integer.MAX_VALUE;
 }
 int ret = 1;
 if((dividend ^ divisor) < 0){
          ret = -1;
     }
 long divid = dividend;
 long divis = divisor;
 long result = helpDivide(Math.abs(divid),Math.abs(divis));
 if(result > Integer.MAX_VALUE && ret == 1){
 return Integer.MAX_VALUE;
 }
     return ret * (int)result;
}
public long helpDivide(long dividend, long divisor){
if(dividend < divisor){
return 0;
}else{
long sub = 0;
int i = 1;
int count = 0;
for(;i < 32 ;i++){
     if((dividend >> i) < divisor){
     break;
     }
     count ++;
     }
     sub = dividend - (long)(Math.pow(2,count)*divisor);
     return (long)Math.pow(2,count)+helpDivide(sub,divisor);
}
}
}

4,此外还有一种其他的思考方式我们看除数不断的调整,直到调整到刚好是不大于被除数,看增加了多少倍,此刻 82.64% 

public class Solution {
     public  int divide(int dividend, int divisor) {
	   if (divisor == 0 || (dividend == Integer.MIN_VALUE && divisor == -1))
            return Integer.MAX_VALUE;;
        int sign = ((dividend ^ divisor) < 0) ? -1 : 1;
        long dvd = Math.abs((long)dividend);
        long dvs = Math.abs((long)divisor);
        int res = 0;
        while (dvd >= dvs) { 
            long temp = dvs, multiple = 1;
            while (dvd >= (temp << 1)) {
                temp <<= 1;
                multiple <<= 1;
            }
            dvd -= temp;
            res += multiple;
        }
        return sign == 1 ? res : -res; 
	 }
	
}


5、由于LeetCode 本身只是调用方法,并不判断算法有没有使用减法,我们看看使用除法的效率, 50 ms,击败14.19%

public class Solution {
     public  int divide(int dividend, int divisor) {
        if(dividend == -2147483648 && divisor == -1){
            return Integer.MAX_VALUE;
        }
        return dividend/divisor;
	 }
}

6、当然啦,我们看看用C语言需要多少秒 6秒

int divide(int dividend, int divisor) {
	   if (!divisor || ((dividend ^ divisor) == 2147483647))
            return INT_MAX;
        int sign = ((dividend ^ divisor) < 0) ? -1 : 1;
        long dvd = labs(dividend);
        long dvs = labs(divisor);
        int res = 0;
        while (dvd >= dvs) { 
        long temp = dvs, multiple = 1;
            while (dvd >= (temp << 1)) {
                temp <<= 1;
                multiple <<= 1;
            }
            dvd -= temp;
            res += multiple;
        }
        return sign == 1 ? res : -res; 
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值