我的LeetCode代码仓:https://github.com/617076674/LeetCode

原题链接:https://leetcode-cn.com/problems/divide-two-integers/description/

题目描述:

知识点:二分搜索

思路一:将除法改为多次减法运算(LeetCode中超时)

虽然这个思路在LeetCode中超时了,但这个思路还是有很多值得注意的点。

(1)为防止越界,将所有的运算数都转换成long类型的数据来进行运算。

(2)设立flag来通过运算数的正负提前标记结果的正负,之后的运算全部转换成正数的运算。

这个思路的时间复杂度是O(dividend / divisor),空间复杂度是O(1)。

JAVA代码:

public class Solution {
	
	public int divide(int dividend, int divisor) {
		if(dividend == 0) {
			return 0;
		}
        //set a flag to record the result is positive or negative
		Boolean flag = true;
		if((dividend < 0 && divisor > 0) || (dividend > 0 && divisor < 0)) {
			flag = false;
		}
		long tempDividend = (long)dividend;
		long tempDivisor = (long)divisor; 
		if(tempDividend < 0) {
			tempDividend = -tempDividend;
		}
		if(tempDivisor < 0) {
			tempDivisor = -tempDivisor;
		}
		long result = 0;
		while(tempDividend >= tempDivisor) {
			tempDividend -= tempDivisor;
			result++;
		}
		if(flag) {
			if(result > Integer.MAX_VALUE) {
				return Integer.MAX_VALUE;
			}else {
				return (int)result;
			}
		}else {
			if(-result < Integer.MIN_VALUE) {
				return Integer.MAX_VALUE;
			}else {
				return (int)(-result);
			}
		}
    }
}

思路二:对思路一的改进,每一次减去的数在倍增

对于思路一而言,其每次减少的数都是divisor,该数一直保持不变。我们可以想象,如果这个divisor绝对值很小,比如是1,而dividend的绝对值很大,比如是Integer.MAX_VALUE,那么就要进行Integer.MAX_VALUE次减法,这个时间复杂度是难以接受的。

题目中要求不能用乘法和除法,但我们可以对减数进行倍增操作。对于dividend,如果dividend - divisor > 0,那么我们下一次减去的数不是divisor,而是divisor + divisor,这样倍增减数的操作可以使我们的时间复杂度到达O(log(dividend / divisor))的级别。而空间复杂度依然保持O(1)的级别。

对于最乐观的情况,假设divisor + divisor * 2 + divisor * 2 ^ 2 + divisor * 2 ^ 3 + ... + divisor * 2 ^ n = dividend。那么我们总共只进行了n次操作,这个时间复杂度显然就是O(log(dividend / divisor))。而如果divisor + divisor * 2 + divisor * 2 ^ 2 + divisor * 2 ^ 3 + ... + divisor * 2 ^ n > dividend,但是divisor + divisor * 2 + divisor * 2 ^ 2 + divisor * 2 ^ 3 + ... + divisor * 2 ^ (n - 1) < dividend,那么我们就要以dividend - (divisor + divisor * 2 + divisor * 2 ^ 2 + divisor * 2 ^ 3 + ... + divisor * 2 ^ (n - 1))为被减数进行重复的操作,即从divisor开始减起。直至我们的被减数小于divisor为止。

而对于结果的值,我们需要根据flag还有是否越界来讨论清楚各种情况。

JAVA代码:

public class Solution {

	public int divide(int dividend, int divisor) {
		if(dividend == 0) {
			return 0;
		}
        //set a flag to record the result is positive or negative
		Boolean flag = true;
		if((dividend < 0 && divisor > 0) || (dividend > 0 && divisor < 0)) {
			flag = false;
		}
		long tempDividend = (long)dividend;
		long tempDivisor = (long)divisor; 
		if(tempDividend < 0) {
			tempDividend = -tempDividend;
		}
		if(tempDivisor < 0) {
			tempDivisor = -tempDivisor;
		}
		long result = 0;
		while(tempDividend >= tempDivisor) {
			long k = 1;
			long temp = tempDivisor;
			while(tempDividend >= temp) {
				tempDividend -= temp;
				result += k;
				k += k;
				temp += temp;
			}
		}
		if(flag) {
			if(result > Integer.MAX_VALUE) {
				return Integer.MAX_VALUE;
			}else {
				return (int)result;
			}
		}else {
			if(-result < Integer.MIN_VALUE) {
				return Integer.MAX_VALUE;
			}else {
				return (int)(-result);
			}
		}
	}
}

LeetCode解题报告:

 

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐