29. Divide Two Integers
Leetcode: https://leetcode.com/problems/divide-two-integers/
Given two integers dividend
and divisor
, divide two integers without using multiplication, division, and mod operator.
The integer division should truncate toward zero, which means losing its fractional part. For example, 8.345
would be truncated to 8
, and -2.7335
would be truncated to -2
.
Return the quotient after dividing dividend by divisor
.
Note: Assume we are dealing with an environment that could only store integers within the 32-bit signed integer range: [−2^31, 2^31 − 1]
. For this problem, if the quotient is strictly greater than 2^31 - 1
, then return 2^31 - 1
, and if the quotient is strictly less than -2^31
, then return -2^31
.
Example 1:
Input: dividend = 10, divisor = 3
Output: 3
Explanation: 10/3 = 3.33333.. which is truncated to 3.
Example 2:
Input: dividend = 7, divisor = -3
Output: -2
Explanation: 7/-3 = -2.33333.. which is truncated to -2.
Constraints:
-2^31 <= dividend, divisor <= 2^31 - 1
divisor != 0
Solution
Inspired by this solution.
But here, we ONLY use the int32/16/8
, and DO NOT use long long
or int64
.
Suppose what we need to compute is a / b
.
If we are permitted to use multiplication operation, then our code will be like:
int k = 1;
while (b * k <= a) k++;
return k;
// or
int k = 0;
while (a >= b) a -= b, k++;
return k;
However, *
operation is not allowed to be used here. But we can use shift operation <<
to simulate *
.
Consider a special case, if we are computing n / 32
, then it's easy to see that we should return n >> 5
, since 32 = 2^5
.
For the common cases, they are similar. If we are computing 33 / 6
,
- First, find out the maximum
k
satisfying6 * 2 ^ k <= 33
. (Obviously, k = 2 here, and this means we can minus2^k * 6
from 33, and this will cause our quotient increase2^k
.) - Then the remained number is
33 - 6 * 2^k = 9
, continue computing the maximumk
satisfying6 * 2^k <= 9
. (k = 0
here.) - The remained number is 3 now, and 3 can not be divided by 6.
Sum up all of the 2^k
, we can get final quotient ret = 2^2 + 2 ^ 0 = 5
.
From now, we can got 1st version of code.
#define SIGNBIT(x) (((uint32_t)(x) >> 31) & 1)
class Solution {
public:
const int INTMIN = (1 << 31);
const int INTMAX = ~INTMIN;
int divide(int dividend, int divisor)
{
if (dividend == INTMIN && divisor == -1) return INTMAX;
uint8_t sign = SIGNBIT(dividend) ^ SIGNBIT(divisor);
uint32_t a = abs(dividend), b = abs(divisor), ret = 0;
while (a >= b)
{
uint32_t tmp = b, cnt = 1;
while ((tmp << 1) <= a)
tmp <<= 1, cnt <<= 1;
a -= tmp, ret += cnt;
}
return sign ? -ret : ret;
}
};
However, there is an issue since we are only permitted to use INT32
.
Suppose the input is 0x80000000 / b
, and b = 2 ^ k (e.g. 1, 2, 4, 8, 16 ...)
.
In the internal loop:
uint32_t tmp = b, cnt = 1;
while ((tmp << 1) <= a) tmp <<= 1, cnt <<= 1;
When tmp = b
grows up to 0x80000000
, tmp << 1
is still less equal than a
because of the overflow!
Hence we add a if
branch to handle this case.
#define SIGNBIT(x) (((uint32_t)(x) >> 31) & 1)
class Solution {
public:
const int INTMIN = (1 << 31);
const int INTMAX = ~INTMIN;
int divide(int dividend, int divisor)
{
if (dividend == INTMIN && divisor == -1) return INTMAX;
uint8_t sign = SIGNBIT(dividend) ^ SIGNBIT(divisor);
uint32_t a = abs(dividend), b = abs(divisor), ret = 0;
if (a == INTMIN && (b & (b - 1)) == 0)
{
uint8_t cntZero = 0;
while (b >> 1) b >>= 1, cntZero += 1;
a >>= cntZero;
return sign ? -a : a;
}
while (a >= b)
{
uint32_t tmp = b, cnt = 1;
while ((tmp << 1) <= a)
tmp <<= 1, cnt <<= 1;
a -= tmp, ret += cnt;
}
return sign ? -ret : ret;
}
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架