Problem: Divide two integers without using multiplication, division and mod operator.
Since we cannot use multiplication, division or mod operator, what's left is addition, subtraction and bit operation.
The "gotcha" in this problem:Math.abs(Integer.MIN_VALUE) will overflow. That's why we need to put the result in along type of variable.
Solution 1: A naive solution is to keep subtracting the divisor from the dividend until the dividend is less than divisor, and count the number of subtractions.
Code 1: Time Complexity: O(N), Space Complexity: O(1)
public class Solution {
public int divide(int dividend, int divisor) {
if (divisor == 0 || dividend == 0) {
return 0;
}
boolean neg = (dividend > 0 && divisor < 0) || (dividend < 0 && divisor > 0);
int counter = 0;
long a = (long)Math.abs(dividend);
long b = (long)Math.abs(divisor);
while (a >= 0) {
++counter;
a-= b;
}
return neg ? -counter : counter;
}
}
The problem with solution 1 is that it is slow; if dividend is very large and divisor is very small, then the OJ will TLE.
Solution 2: An improved solution is to use the fact that any integer could be represented like the following:
integer = a0*2^0 + a1*2^1 + a2*2^2 + ... + an*2^n
so we keep left shifting the divisor until such that, if we left shift one more, then the divisor will be larger than the dividend. Then we subtract the divisor from the dividend and repeat the aforementioned process.
Code 2: Time Complexity: O(lgN), Space Complexity: O(1)
public class Solution {
public int divide(int dividend, int divisor) {
if (divisor == 0 || dividend == 0) {
return 0;
}
// another way to check whether two integers have the same sign:
// also notice the ">>>" -- logical right shift,
// which does not preserve the sign of number
boolean neg = (dividend^divisor)>>>31 == 1 ? true : false;
//boolean neg = (dividend > 0 && divisor < 0) || (dividend < 0 && divisor > 0);
long a = Math.abs((long)dividend);
long b = Math.abs((long)divisor);
int result = 0;
while (a >= b) {
int counter = 0;
//while (a >= (b << 1)) {
while (a >= (b << counter)) {
++counter;
}
a -= (b << (counter - 1));
result += (1 << (counter - 1));
}
return neg ? -result : result;
}
}