The "Divide Two Integers" problem asks you to divide two integers, dividend
and divisor
, without using multiplication, division, or modulo operators. The result should be the quotient after dividing dividend
by divisor
. If the division result overflows (i.e., is outside the range of a 32-bit signed integer), you must return 231 - 1
(which is 2147483647). Both dividend
and divisor
are 32-bit signed integers. The division should truncate toward zero (i.e., discard the fractional part).
*
), division (/
), or modulo (%
) operators.dividend
by divisor
.2147483647
.
At first glance, dividing without the division operator seems tricky. The most basic approach is repeated subtraction: subtract the divisor
from the dividend
until the dividend
becomes less than the divisor
. Each subtraction counts as one toward the quotient. However, this method is inefficient for large numbers, as it could require billions of iterations.
To optimize, we can use bit manipulation. If we can subtract larger multiples of the divisor
at once, we can reduce the number of steps. This is similar to how we do long division by hand, taking away the biggest possible chunk each time. By doubling the divisor
(using left shifts), we can quickly find how many times the divisor
fits into the remaining dividend
and accumulate the answer efficiently.
Here's how we can efficiently solve the problem step-by-step:
dividend
is INT_MIN
and divisor
is -1
, return INT_MAX
to prevent overflow.divisor
is 1
or -1
, simply return dividend
or -dividend
(handling overflow).INT_MIN
has no positive counterpart).divisor
(using left shift) as much as possible without exceeding the dividend
.dividend
and add the multiple to the result.dividend
is less than the divisor
.This approach is efficient because each time we subtract the largest possible chunk, reducing the number of iterations to O(log N).
Let's use the example: dividend = 43
, divisor = 8
.
quotient = 0
.
8
that is less than or equal to 43
:
The process quickly reduces the dividend
by subtracting large chunks, making it much faster than repeated subtraction.
dividend
. Each loop iteration reduces the problem size by a factor of two.
The "Divide Two Integers" problem demonstrates how to implement division without using the division operator, by leveraging bit manipulation and subtraction. The key insight is to subtract the largest possible multiples of the divisor using left shifts, mimicking the process of long division for efficiency. This reduces the number of steps from linear to logarithmic, making the solution both elegant and practical.
class Solution:
def divide(self, dividend: int, divisor: int) -> int:
INT_MAX = 2 ** 31 - 1
INT_MIN = -2 ** 31
# Handle overflow
if dividend == INT_MIN and divisor == -1:
return INT_MAX
# Determine sign
negative = (dividend < 0) != (divisor < 0)
dividend, divisor = abs(dividend), abs(divisor)
quotient = 0
for i in range(31, -1, -1):
if (dividend >> i) >= divisor:
quotient += 1 << i
dividend -= divisor << i
return -quotient if negative else quotient
class Solution {
public:
int divide(int dividend, int divisor) {
long long INT_MAX = 2147483647;
long long INT_MIN = -2147483648;
if (dividend == INT_MIN && divisor == -1) return INT_MAX;
bool negative = (dividend < 0) != (divisor < 0);
long long dvd = abs((long long)dividend);
long long dvs = abs((long long)divisor);
int quotient = 0;
for (int i = 31; i >= 0; i--) {
if ((dvd >> i) >= dvs) {
quotient += 1 << i;
dvd -= dvs << i;
}
}
return negative ? -quotient : quotient;
}
};
class Solution {
public int divide(int dividend, int divisor) {
int INT_MAX = Integer.MAX_VALUE;
int INT_MIN = Integer.MIN_VALUE;
if (dividend == INT_MIN && divisor == -1) return INT_MAX;
boolean negative = (dividend < 0) != (divisor < 0);
long dvd = Math.abs((long)dividend);
long dvs = Math.abs((long)divisor);
int quotient = 0;
for (int i = 31; i >= 0; i--) {
if ((dvd >> i) >= dvs) {
quotient += 1 << i;
dvd -= dvs << i;
}
}
return negative ? -quotient : quotient;
}
}
var divide = function(dividend, divisor) {
const INT_MAX = 2147483647;
const INT_MIN = -2147483648;
if (dividend === INT_MIN && divisor === -1) return INT_MAX;
let negative = (dividend < 0) !== (divisor < 0);
let dvd = Math.abs(dividend);
let dvs = Math.abs(divisor);
let quotient = 0;
for (let i = 31; i >= 0; i--) {
if ((dvd >> i) >= dvs) {
quotient += 1 << i;
dvd -= dvs << i;
}
}
return negative ? -quotient : quotient;
};