Leetcode: Divide Two Integers

本文介绍了一种不使用乘法、除法和取模运算实现整数除法的方法。通过两种算法解决该问题:一种是朴素减法法,时间复杂度为O(N),另一种是利用位操作改进算法,时间复杂度为O(lgN)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值