【刷穿剑指】剑指 Offer II 001. 整数除法

今天开坑 剑指 Offer 题目二刷,剑指的每一个题目都是非常经典且经常考察的题目,一共 119 道题目,针对不同的数据结构与算法,有许多难度不一的好题目。希望这次二刷能巩固第一次所学,并撰写自己的题解!大家和我一起加油吧!同时我会把力扣原题的链接附上。

整数篇 - 剑指 Offer II 001. 整数除法

原题链接:剑指 Offer II 001. 整数除法

【刷穿剑指】剑指 Offer II 001. 整数除法_第1张图片

解析

有一说一,本书开篇第一题虽说标签是简单题,但绝对有中等难度。

首先注意到不能使用的符号,如果不考虑位运算的话,普通解法大概就是循环做减法,但是如果被除数过大除数过小则可能导致超时。

是故,考虑快速幂(还是叫快速乘)可以达到 O(logn),大概想法就是如果被除数大于除数,继续判断被除数是否大于除数的两倍,如果是,继续判断是否为四倍,如果不是,则商加2,被除数减去除数的两倍,循环直至被除数小于除数。

此外,按题目要求,我们需要考虑溢出的问题,为了防止溢出,因为 -2^31 转化为正数 2^31 会溢出,所以我们可以把 a 和 b 也就是被除数和除数都转化为正数。如果想不来负数运算,可以结合草纸画个数轴。

具体代码如下:

代码

class Solution {
    public int divide(int a, int b) {
        // 特殊情况,负数最小值除以-1导致溢出
        if (a == Integer.MIN_VALUE && b == -1) {
            return Integer.MAX_VALUE;
        }

        // 定义负数标志变量
        // 将a、b 转为负数
        int negetive = 2;
        if (a > 0) {
            a = -a;
            negetive--;
        }
        if (b > 0) {
            b = -b;
            negetive--;
        }

        int res = divideCore(a, b);
        return negetive == 1 ? -res : res;
    }

    private int divideCore(int a, int b) {
        int res = 0;

        while (a <= b) {
            int value = b;
            int quotient = 1;
            // 第一个条件防止下一次快速幂溢出,第二个条件保证 a 小于下一次快速幂
            while (value >= -Math.pow(2, 30) && a <= value + value) {
                quotient += quotient;
                value += value;
            }
            
            res += quotient;
            a -= value;
        }

        return res;
    }
}

写文不易,求个关注,没有关注,点赞也行!

【刷穿剑指】剑指 Offer II 001. 整数除法_第2张图片

你可能感兴趣的:(刷题记录,算法,题解,面试)