From 49de5f8f13a80d1878a15c3a892df06cd2db8ccf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=94=90=E6=A0=91=E6=A3=AE?= <14021051@buaa.edu.cn> Date: Mon, 24 Dec 2018 23:14:53 +0800 Subject: [PATCH] Create 29. Divide Two Integers.md --- 29. Divide Two Integers.md | 48 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 29. Divide Two Integers.md diff --git a/29. Divide Two Integers.md b/29. Divide Two Integers.md new file mode 100644 index 0000000..96e85c4 --- /dev/null +++ b/29. Divide Two Integers.md @@ -0,0 +1,48 @@ +# [29. Divide Two Integers](https://leetcode.com/problems/divide-two-integers/) +# 思路 +不使用取模、除法等操作求两数相除的商。 +常规思路就是不断循环用被除数减去除数然后记录被减的次数即商,但是亲测会超时。 +既然每次减去除数会超时,那么一次性地减去除数的2倍、4倍、8倍......(之所以取2的次方倍是为了移位操作即可快速实现)呢,基于这个思路,我们有以下算法: +假设除数和被除数都是正数,例如考虑15除3,先用15-3发现结果等于12>3,再尝试用15-6发现结果得9>3,再尝试用15-12发现结果3=3,再尝试用15减去24发现不够减, +则应该用15-12然后余3,此时商得4;然后再考虑3除3,依然用上面的思路,得到商为1,最终的结果就是将每一步得到的商相加即可。 +如果是负数的话先取绝对值最后判断符号即可。 +另外需要考虑两个溢出的情况: +* `dividend == INT_MIN && divisor == -1`,结果是`-INT_MIN`超出了int的表示范围。 +* ·dividend == INT_MIN && divisor == 1`,结果是`INT_MIN`虽然没有超过范围,但是我们是按照绝对值计算结果的,所以计算过程res也会溢出。 + +另外需要注意的是再用abs(x)求绝对值的时候一定要先将x转换成long long型这样abs(x)返回的才是long long型,保证不溢出。否则若x=INT_MIN的话求绝对值就超过 +int型表示范围了。 + +[参考](https://leetcode.com/problems/divide-two-integers/discuss/13407/Detailed-Explained-8ms-C%2B%2B-solution) + +# C++ +``` C++ +class Solution { +public: + int divide(int dividend, int divisor) { + if(dividend == 0) return 0; + if(dividend == INT_MIN && divisor == -1) return INT_MAX; + if(dividend == INT_MIN && divisor == 1) return INT_MIN; + int res = 0; + long long dvd = abs((long long)dividend); // 一定要先将dividend和divisor转换成long long型这样abs才返回long long型 + long long dvs = abs((long long)divisor); + long long dvs_bk = dvs; // 除数备份 + + while(dvd >= dvs){ + int curr = 1; + dvs <<= 1; + while(dvd - dvs >= 0){ + curr *= 2; + dvs <<= 1; + } // dvd < dvs + dvs >>= 1; + dvd -= dvs; + dvs = dvs_bk; + res += curr; + } + if(dividend > 0 && divisor < 0) res *= -1; + else if(dividend < 0 && divisor > 0) res *= -1; + return res; + } +}; +```