首页 > 代码库 > LeetCode 28 Divide Two Integers

LeetCode 28 Divide Two Integers

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

思路:1.先将被除数和除数转化为long的非负数,注意一定要为long,因为Integer.MIN_VALUE的绝对值超出了Integer的范围。

          2.常理:任何正整数num都可以表示为num=2^a+2^b+2^c+...+2^n,故可以采用2^a+2^b+2^c+...+2^n来表示商,即dividend=divisor*(2^a+2^b+2^c+...+2^n),(a,b,c,....m互不相等,且最大为31,最小为0)。而商的最大值为Integer.MIN_VALUE的绝对值,商最多有32个2的指数次相加,故时间复杂度为常数。

          3.divisor*2^a用计算机表示为divisor<<a;

          注意:若每次只加一个divisor,则面对Integer.MAX_VALUE除以一个很小的常数(eg:1,2,3),会超时。

public class Solution {
	public int divide(int dividend, int divisor) {

		boolean positive = true;
		if((dividend>0&&divisor<0)||(dividend<0&&divisor>0))
			positive = false;
		long did=dividend>=0?(long)dividend:-(long)dividend;
		long dis=divisor>=0?(long)divisor:-(long)divisor;

		long quotients = positiveDivide(did, dis);
		if (!positive)
			return (int)-quotients;
		return (int)quotients;
	}

	public long positiveDivide(long did, long dis) {
		long[] array = new long[32];
		long sum = 0;
		int i = 1;
		long quotients = 0;
		if(dis==1) return did;//为了避免-did=Integer.MIN_VALUE,而dis=1,出现问题
		for (array[0]=dis; i < 32 && array[i - 1] <= did; i++) 
			array[i] = array[i - 1] << 1;
		
		for (i = i - 2; i >= 0; i--) {
			if (sum <= did - array[i]) {
				sum += array[i];
				quotients += 1 << i;
			}
		}		
		return quotients;
	}
}

优化版,减小内存的消耗,不申请动态数组

public class Solution {
	public int divide(int dividend, int divisor) {

		boolean positive = true;
		if((dividend>0&&divisor<0)||(dividend<0&&divisor>0))
			positive = false;
		long did=dividend>=0?(long)dividend:-(long)dividend;
		long dis=divisor>=0?(long)divisor:-(long)divisor;

		long quotients = positiveDivide(did, dis);
		if (!positive)
			return (int)-quotients;
		return (int)quotients;
	}
	
	public long positiveDivide(long did, long dis) {
		long sum = 0;
		long quotients = 0;
		if(dis==1) return did;//为了避免-did=Integer.MIN_VALUE,而dis=1,出现问题
		
		//sum从divisor*2^31的开始加起,不能加则试试加上divisor*2^30,
		//若不能则试试divisor*2^29,依此类推
		for (int i = 31; i >= 0; i--) {
			long temp=dis<<i;//该式为divisor*2^a
			
		//sum<=dividend则说明dividend大于divisor*(2^m+...+2^i),m最大为31
		if (sum <= did - temp) {
				sum += temp;
				quotients += 1 << i;//2^i
			}
		}		
		return quotients;
	}
}