剑指 Offer II 001. 整数除法

剑指 Offer II 001. 整数除法

结果

执行结果:通过显示详情〉
执行用时:1 ms ,在所有Java提交中击败了 64.49%的用户
内存消耗:38.9 MB ,在所有Java提交中击败了50.17%的用户
通过测试用例:992/992

花费了一天时间解决。

思路

首先,边界问题:[ − 2 31 -2^{31} 231, 2 31 − 1 2^{31}-1 2311],即[-2147483648, 2147483647],负数比正数多一个,负转正时会出问题,因此都转为负数来处理。

其次,关于计算思路,我有两种:

  • 一种是蠢办法,一直减那个除数,会超时

  • 另一种是

    从除数出发,一直叠加,每次在上一次的基础上叠加,并使用一个数组(栈)来记录。

    加到顶以后,又从栈的最高层慢慢减下来,并折算次数,这个次数和栈的下标有关。

实现难处:各种边界,相互牵扯的映射关系使得调试很久。

code

class Solution {
    //都当成负数处理,就不会有负转正的溢出错误
    public int divide(int a, int b) {
        
        //判断答案正负号
        boolean flag = (a>0&&b>0)||(a<0&&b<0)?true:false;

        //排除边界和一些特定情况
        if(a == -2147483648){
            if (b==1){
                // System.out.println("xxx");
                return -2147483648;
            } 
            else if(b==-1) return 2147483647;//溢出
        }

        if (b == -2147483648){
            if(a == -2147483648) return 1;
            else return 0;
        }
        // System.out.println(a+" "+b);

        //把a、b转成负数
        if (a > 0) a = -a;
        if (b > 0) b = -b;
        // System.out.println(a+" "+b);

        if (a>b) return 0;


        // 计算其他非0情况
        int[] divideStack = new int[32]; //0号位不放
        
        int divideNum = b; //算子默认从b的最小值开始
        divideStack[1] = divideNum;
        int divideStackIndex = 1; 
        int count = 1; //计算次数

        //算子叠加
        while(true){
                divideNum = divideNum+divideNum;
                
                if (divideNum > a && divideNum<0){
                    divideStackIndex++;
                    divideStack[divideStackIndex] = divideNum;
                }else break;  
        }
        count =(int) Math.pow(2,divideStackIndex-1);
        // for (int d:divideStack){
        //     System.out.println(d);
        // }
        // System.out.println(divideNum +"\t" + divideStack[divideStackIndex] +"\t"+divideStackIndex+ "\t" +count);
        
        a = a - divideStack[divideStackIndex];
       //算子衰减 从最大算子开始减 因为此时剩余的数比最大算子大,但是小于2倍最大算子
        while(divideStackIndex>0 ){
            int temp = a - divideStack[divideStackIndex];
            if (temp <= b || temp==0){
                count = count + (int)Math.pow(2,divideStackIndex-1);
                a = temp;
            }else if (temp > b && temp <0 ){
                count++;
            }
            // System.out.println(a+"\t"+divideStack[divideStackIndex]+"\t"+divideStackIndex+ "\t"+count);
            divideStackIndex--;
        }
        return flag?count:-count;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值