1. 程式人生 > >LeetCode 28 Divide Two Integers

LeetCode 28 Divide Two Integers

範圍 long mod max article edi 優化 指數 故障

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; } }



LeetCode 28 Divide Two Integers