0
点赞
收藏
分享

微信扫一扫

剑指offer专项突破版

求索大伟 2022-03-18 阅读 87

面试题1:整除除法

力扣连接:https://leetcode-cn.com/problems/xoh6Oh/submissions/

题目描述

样例输入1

样例输出1

样例输入2

样例输出2

样例输入3

样例输出3


暴力循环O(n)

这个题目限制我们不能使用乘号、除号进行运算。一个直观的解法就是基于减法实现除法。
例如,为了求得15/2的商,可以不断地从15里减去2,当减去7个2之后余数是1,此时不能再减去更多的2,因此15/2的商是7。可以用循环实现这一过程。在实现之前,先考虑数据溢出的问题:

  1. 对于int类型来说,能表示的数据范围在[-231,231-1]之间,只有当a=-231,b=-1的时候a/b的结果超过int所能表示的最大整数范围造成数据溢出,此时直接返回INT_MAX即可。
  2. 对于除数或者被除数是负数的情况,考虑到负数-231变成正数会造成数据溢出,所以把被除数和除数都变成负数,再进行运算。
class Solution {
public:
    int divide(int a, int b) {
        if(a==INT_MIN && b==-1) return INT_MAX;
        int ans=0;
        int flag=2;
        if(a>0) {a=-a;flag--;}
        if(b>0) {b=-b;flag--;}
        while(a<=b){
            ans++;
            a-=b;
        }
        if(flag==1) ans=-ans;
        return ans;
    }
};

这个程序的时间复杂度是O(n),当a非常大而b又非常小的时候,会超出时间限制,所以要做出优化。


优化O(logn)

在暴力循环的基础上进行优化。(此时被除数和除数都是负数)
当被除数小于等于除数时,继续比较判断被除数是否小于等于除数的2倍,如果是,则继续判断被除数是否小于等于除数的4倍、8倍…等。如果被除数a最多小于等于除数的2k倍,那么被除数减去除数的2k倍,这部分的商是2k,然后将被除数重复前面的步骤直到被除数a大于b。

举例

a=15,b=3
res=0记录最后结果
全部变为负数
a=-15,b=-3

第一次循环

pin=1记录本部分的商
value=b记录除数
-15 < -3-3 ----------->value=-6 ;pin=2
-15 < -6-6 ----------->value=-12;pin=4
-15 > -12-12---------->res=4;a=-3

第二次循环

pin=1
value=b
-3 > -3-3---------->res=5;a=0

第三次循环

a>b----------> 退出循环
因为原本两个数都是正数所以返回5;

class Solution {
public:
    int divide(int a, int b) {
        if(a==INT_MIN && b==-1) return INT_MAX;
        if(b==1) return a;
        int ans=0;
        int flag=2;
        if(a>0) {a=-a;flag--;}
        if(b>0) {b=-b;flag--;}
        while(a<=b){
            int value=b;//除数
            int pin=1;//商
            while(value>=INT_MIN/2 && a<=value+value){
                /*为了防止value+value之后产生数据溢出,
                应该让value>=INT_MIN的一半。
                之所以是大于等于是因为value是一个负数*/
                pin+=pin;
                value+=value;
            }
            ans+=pin;
            a-=value;
        }
        if(flag==1) ans=-ans;
        return ans;
    }
};

在这里插入图片描述

举报

相关推荐

0 条评论