LeetCode第29题两数相除

简介: 这篇文章介绍了LeetCode第29题"两数相除"的解题方法,通过使用加法、减法和二进制位移法代替常规的乘除操作,并考虑了整数溢出问题,提供了一种高效的算法解决方案。

继续打卡算法题,今天学习的是LeetCode的第29题两数相除,这道题目是道中等题。算法题的一些解题思路和技巧真的非常巧妙,每天看一看算法题和解题思路,我相信对我们的编码思维和编码能力有一些提升。

image.png

分析一波题目

这道题其实挺有意思的,两数相除不适用除法,乘法,取余。

那么我们只能使用加法,减法,二进制位移法了。

如果使用位移法,我们可以将除数不断的左位移,进行双倍扩容增长,同时记录扩容次数,如果扩容后的值大于被除数,说明到达了除数接近的值,这样不是每次增加除数。

同时本题需要考虑整数越界的情况。我们可以将被除数和除数统一转换成long类型防止溢出

编码解决

class Solution {
   
   
    public int divide(int dividend, int divisor) {
   
   

        // 当除数为1,直接返回被除数
        if (divisor == 1) {
   
   
            return dividend;
        }
        // 当除数为-1且被除数为Integer.MIN_VALUE时,将会溢出,返回Integer.MAX_VALUE
        if (divisor == -1 && dividend == Integer.MIN_VALUE) {
   
   
            return Integer.MAX_VALUE;
        }

        // 把被除数与除数调整为正数,为防止被除数Integer.MIN_VALUE转换为正数会溢出,使用long类型保存参数
        if (dividend < 0 && divisor < 0) {
   
   
            return divide(-(long) dividend, -(long) divisor);
        } else if (dividend < 0 || divisor < 0) {
   
   
        //虽然有负数,统一转换成正数
            return -divide(Math.abs((long) dividend), Math.abs((long) divisor));
        } else {
   
   
            return divide((long) dividend, (long) divisor);
        }
    }

    public int divide(long dividend, long divisor) {
   
   
        // 如果被除数小于除数,结果明显为0
        if (dividend < divisor) {
   
   
            return 0;
        }
        long sum = divisor; // 记录用了count个divisor的和
        int count = 1; // 使用了多少个divisor
        while (dividend >= sum) {
   
   
            // 每次翻倍 左移就是相乘
            sum <<= 1;
            //计数也翻倍
            count <<= 1;
        }

        // 此时dividend < sum
        sum >>>= 1; //扩容的除数,需要回退1位
        count >>>= 1; //计数也需要回退1位
        // 此时dividend >= sum
        // 将count个divisor从dividend消耗掉,剩下的还需要多少个divisor交由递归函数处理
        return count + divide(dividend - sum, divisor);
    }
}

总结

这个题目有两个技巧可以运用到其他问题上:

  • 防止整数溢出,将数转换成long类型
  • 在某些场景下,如果不能使用乘除运算的时候,我们可以想到使用二进制形式位移运算

一个数左移1位就是乘以2,左移n位就是乘以2的n次方,左移运算效率比乘法效率高

一个数右移1位就是除以2,右移n位就是除以2的n次方,当得到的商不是整数时会往小取整

相关文章
|
3月前
|
存储
Leetcode第29题(两数相除)
LeetCode第29题要求使用不包含乘法、除法和mod运算符的方法计算两个整数的商,通过记录结果的正负,将问题转化为负数处理,并利用二进制幂次方的累加来逼近除数,最后根据结果的正负返回相应的商。
22 0
|
8月前
leetcode-29:两数相除
leetcode-29:两数相除
53 0
|
存储 算法 安全
LeetCode - #29 两数相除
不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。
|
存储 算法 测试技术
leetcode:29.两数相除
给定两个整数,被除数 dividend和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。
109 0
|
存储 算法 Java
LeetCode 27移除元素&28实现strStr()&29两数相除
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
110 0
LeetCode 27移除元素&28实现strStr()&29两数相除
|
存储 算法
【刷穿 LeetCode】29. 两数相除 : 对限制条件的两种理解,以及两种倍增实现
【刷穿 LeetCode】29. 两数相除 : 对限制条件的两种理解,以及两种倍增实现
☆打卡算法☆LeetCode 29、两数相除 算法解析
“给定两个整数,进行相除,不能使用乘法、除法和mod运算符。”