ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

leetcode29.两数相除(中等)

2022-01-11 22:33:07  阅读:204  来源: 互联网

标签:return divisor INT MAX 相除 int leetcode29 dividend 两数


在这里插入图片描述
在这里插入图片描述
思路:二分
乘法:用快速乘来替代。
除法:除以2用>>1来替代
mod:用不到
注意:(dividend / intdivisor)
1:如果除法结果溢出,那么需要返回 2^31-1作为答案。因此在编码之前,我们可以首先对于溢出或者容易出错的边界情况进行讨论
dividend讨论:
(1)INT_MIN : 1 (ans越界:return INT_MIN) -1(最终结果越界:return INT_MAX)
(2)0 : return 0
2:对于一般的情况,根据除数和被除数的符号,需要考虑 4种不同的可能性。因此,为了方便编码,我们可以将被除数或者除数取相反数,使得它们符号相同。如果我们将被除数和除数都变为正数,那么可能会导致溢出。例如当被除数为 -2^31,它的相反数产生了溢出。因此可以考虑将被除数和除数都变为负数,这样就不会有溢出的问题,在编码时只需要考虑1种情况了。
3:二分来源(x y为负数 ,z为正数,z的取值范围为:1到INT_MAX)
x/y==z 转化为:yz>=x>(z+1)y, 问题转化为找最大的z,满足yz大于等于x!!!因此可以用二分。
4:我自己二分的写法习惯用()两个开区间来写,所以,看一下边界,发现INT_MAX得单独考虑下
dividend为INT_MAX : 1(return INT_MAX) -1(return -INT_MAX)
这样二分时右边界初始化可以初始为INT_MAX。

class Solution {
public:
	//m*n大于等于a的话return true 否则false,n是正数
    bool fast_cheng(int m, int n, int a) { 
        int ans = 0;
        while (n) {
            if (n & 1) {
                if (ans < a - m) return false; //ans+m<a转换下,因为m为负数,ans+m可能会越界!!!
                //上面,因为m是负数,所以ans若已经小于a,则直接返回false!!!
                ans += m; //上面先判断再+=,怕ans+m越界!!!
            }
            if(n != 1) {
                if (m < a - m) return false; //若更新后的m已经小于a,说明m*n肯定小于a,返回false!!!
                m += m; //-2147483648 + -2147483648会越界,m+m应该大于a,小于直接return false!!!
            }
            n >>= 1;
        }
        return true; 
    }
    int divide(int dividend, int divisor) {
       
        if (dividend == INT_MIN) {
            if (divisor == 1) return INT_MIN;
            if (divisor == -1) return INT_MAX;
        }
        if (dividend == INT_MAX) {
            if (divisor == 1) return INT_MAX;
            if (divisor == -1) return -INT_MAX;
        }
        if (dividend == 0) return 0;
        bool flag = true;
        if (dividend > 0) { 
            dividend = -dividend;
            flag = !flag;
        }
        if (divisor > 0) {
            divisor = -divisor;
            flag = !flag;
        }
        int l = 0, r = INT_MAX;
        while (l + 1 < r) {
            int mid = l + ((r - l) >> 1); //
            if (fast_cheng(divisor, mid, dividend)) l = mid; //乘法->快速乘
            else r = mid;
        }
        return (flag) ? l : -l;
    }
};

易错点
1:由于判断mid * divisor >= dividend,使用快速乘时要对mid进行移位,因为mid是正数,不能搞错了。
2:使用二分求mid时,/2可以用>>1来写。
3:易错点已经在上面的代码中注释。

标签:return,divisor,INT,MAX,相除,int,leetcode29,dividend,两数
来源: https://blog.csdn.net/zhangjiaji111/article/details/122442835

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有