LeetCode的一个题目 Divide Two Integers

昨天开始刷LeetCode,刚开始做的几个题都没有问题,思路都很流畅,知道遇到了Divide Two Integers这个题目。

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

If it is overflow, return MAX_INT.

题目的描述很简单,就是在不使用乘法、除法和模运算的情况下实现两个整数的除法。

看到这个题目我首先想到的思路是除数一直相加,直到大于被除数,那么相加的次数减1就是我们需要的结果。代码如下:

	public static int divide(int dividend,int divisor){		
		int MAX_INT = 2147483647;
		boolean isReverse = false;
		int mDividend = dividend;
		int mDivisor = divisor;
		if(dividend<0){
			isReverse = !isReverse;
			mDividend = -dividend;
		}
		if(divisor<0){
			isReverse = !isReverse;
			mDivisor = -divisor;
		}
		if(mDividend==0)
			return 0;
		if(mDivisor==0)
			return MAX_INT;
		int result = 1;
		int tmp = mDivisor;
		while (!(mDividend<=tmp)) {
			result++;
			tmp+=mDivisor;
		}
		if(tmp>mDividend)
			result--;
		if(isReverse)
			result = -result;
		return result;
	}
因为考虑到负数的问题,所以显得比较繁琐,事实上核心代码并没有很复杂。但是,在代码提交时报了

Time Limit Exceeded
仔细思考发现,这样子做效率确实比较低,假设被除数是max_int 2147483647,除数是1,那么我们就需要加2147483647次才能得到结果,效率太低了!

那么该如何提高效率呢?二分法。以前每次都是加除数,知道大于除数,假如使用二分法的话,40/2,那么我们2+2<40,4+4<40,8+8<40,16+16<40,32+32>40,再对40-32=8重复上述操作,则可以得到结果。代码如下

	/**
	 * 二分法
	 * @param dividend 被除数
	 * @param divisor 除数
	 * @return
	 */
	public static int divide(int dividend,int divisor){
		int result = 0;
		int MAX_INT = 2147483647;
		boolean isReverse = false;
		if(dividend<0){
			isReverse = !isReverse;
			dividend = -dividend;
		}
		if(divisor<0){
			isReverse = !isReverse;
			divisor = -divisor;
		}
		if(dividend==0)
			return 0;
		if(divisor==0)
			return MAX_INT;
		int tmp = divisor;
		int tmpResult = 1;
		int remainder = dividend;
		while (remainder>=divisor) {
			tmp = divisor;
			tmpResult = 1;
			while ((tmp+tmp)<=remainder) {
				tmp = tmp+tmp;
				tmpResult = tmpResult+tmpResult;
			}
			remainder = remainder - tmp;
			result = result +tmpResult;
		}
		if(isReverse)
			result = -result;
		return result;
	}
但是!但是!!使用二分法还超时!!!使用二分法了你还报超时!效率都已经提高那么多了!!!

天哪!!到底该怎么搞啊?莫非真的要使用位运算吗???如何搞啊????莫非要让我用位运算重新实现一次除法吗?????

好吧,我的错,主要是越界问题没考虑清楚。注意:有可能tmp+tmp越界,同时,当值为-2147483648时,对他取反也会有越界问题。bug修复完成后代码如下:

	/**
	 * 二分法
	 * 我操,越界问题太蛋疼。
	 * @param dividend 被除数
	 * @param divisor 除数
	 * @return
	 */
	public static int divide(int dividend,int divisor){
		long result = 0;
		int MAX_INT = 2147483647;
		boolean isReverse = false;
		long mDividend = dividend;
		long mDivisor = divisor;
		if(dividend<0){
			isReverse = !isReverse;
			mDividend = -mDividend;
		}
		if(divisor<0){
			isReverse = !isReverse;
			mDivisor = -mDivisor;
		}
		if(mDividend==0)
			return 0;
		if(mDivisor==0)
			return MAX_INT;
		long tmp = mDivisor;
		long tmpResult = 1;
		long remainder = mDividend;
		while (remainder>=mDivisor) {
			tmp = mDivisor;
			tmpResult = 1;
			while ((tmp+tmp)<=remainder) {
				tmp = tmp+tmp;
				tmpResult = tmpResult+tmpResult;
			}
			remainder = remainder - tmp;
			result = result +tmpResult;
		}
		if(isReverse)
			result = -result;
		if(result>0&&(int)result<0){
			return MAX_INT;
		}
		return (int) result;
	}

Accepted!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值