zoukankan      html  css  js  c++  java
  • LeetCode 29. Divide Two Integers

    问题链接

    LeetCode 29. Divide Two Integers

    Divide two integers without using multiplication, division and mod operator.

    If it is overflow, return MAX_INT.

    题目解析

    两数相除,不得使用乘法、除法、取模运算。

    解题思路

    题目限制这么大,很明显是要考察专一的知识点,那是什么呢?神奇的 位运算操作,简单来讲就是 二进制 的运用。

    你最初的思路可能是这样子,只运用减法,每次减去除数,最后总能得到结果,没错,但是这样有什么意义呢?我觉得应该可以AC,但也不想去试着写这样的辣鸡代码。一个一个减,多想一下,可不可以多个一起减呢?

    举一个简单的例子,求解40÷3,结果为13(忽略余数),如果一个一个减,在第14次减去3的时候可以知道答案是13。这个13可以可以以另一种方式得到,每一个数都有二进制表示,它的含义是什么呢,其实是多个2的幂值相加,这里的13=8+4+1,意味着40=(8*3)+(4*3)+(1*3)···1,所以问题转化为求这多个2的幂值。

    具体实现,最初的想法是每次循环减一次(1*除数),现在改进后,每次循环减去(最大2的幂值*除数),通过左移运算,每次将幂值<<1(乘2),求得最大2的幂值后,更新被除数和结果。如何求得最大2的幂值,可参考代码理解。

    注意:排除特殊情况,除数为0或者超出int范围。左移运算中,数值范围可能超出int,采用long或者long long都可以。

    参考代码

    class Solution {
    public:
        int divide(int dividend, int divisor) {
            if (!divisor || (dividend == INT_MIN && divisor == -1)) return INT_MAX;
            
            int sign = ((dividend < 0) ^ (divisor < 0)) ? -1 : 1;
            long long dvd = labs(dividend);
            long long dvs = labs(divisor);
            int res = 0;
            while (dvd >= dvs) { 
                long long temp = dvs, multiple = 1;
                while (dvd >= (temp << 1)) {
                    temp <<= 1;
                    multiple <<= 1;
                }
                dvd -= temp;
                res += multiple;
            }
            return sign == 1 ? res : -res; 
        }
    };
    

    参考链接:Detailed Explained 8ms C++ solution


    LeetCode All in One题解汇总(持续更新中...)

    本文版权归作者AlvinZH和博客园所有,欢迎转载和商用,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.


  • 相关阅读:
    可视化工具搭建SVN服务器
    VS添加lib库以及代码中相对路径的问题
    编程:休息片刻的好处
    我的C++笔记
    【转】缩小mysql数据库的ibdata1文件
    MySQL导库命令
    Java中的serialize接口与transient关键字
    蓝桥杯 算法提高 01背包
    蓝桥杯 算法提高 01背包
    蓝桥杯 算法提高 快乐司机
  • 原文地址:https://www.cnblogs.com/AlvinZH/p/8643676.html
Copyright © 2011-2022 走看看