Leetcode: Divide Two Integers

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;
    }
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值