2021-09-28 剑指offer刷题9.28

剑指offer(专项突破版)日常刷题 1~3

1.给定两个整数 a 和 b ,求它们的除法的商 a/b ,要求不得使用乘号 ‘*’、除号 ‘/’ 以及求余符号 ‘%’ 。
注意:
整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2
假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231−1]。本题中,如果除法结果溢出,则返回 231 − 1

class Solution {
     public int divide(int a, int b) {
        if (a == Integer.MIN_VALUE && b == -1) {
            return Integer.MAX_VALUE;
        }

        /*
            判断是否同号,同号则 结果为正数
         */
        boolean flag = false;
        if ((a<0 && b<0) || (a>0 && b>0)) {
            flag = true;
        }

        long dividend = Math.abs((long) a);
        long divisor = Math.abs((long) b);
        if (dividend < divisor) {
            return 0;
        }
        /*
            计算 结果的绝对值
         */
        int result = 0;
        int shift = 31;
        while (dividend >= divisor) {
            while (dividend < divisor << shift) {
                shift--;
            }
            dividend -= divisor << shift;
            result += 1 << shift;
        }

        return flag ? result : -result;
    }
}

2.给定两个 01 字符串 a 和 b ,请计算它们的和,并以二进制字符串的形式输出。
输入为 非空 字符串且只包含数字 1 和 0。

class Solution {
    public String addBinary(String a, String b) {
        String ans = ""; // 保存最后的结果
        int carryBit = 0; // 进位
        int curA = a.length() - 1; // 记录当前字符 a 遍历的位置
        int curB = b.length() - 1; // 记录当前字符 b 遍历的位置

        // 遍历字符串,当两个两个字符串 a,b都遍历完了后就结束循环
        while (curA >= 0 || curB >= 0){
            int tmp;// 保存 b对应位 + a 对应位 + 进位 的临时结果
            if(curA < 0)
                tmp = (b.charAt(curB--) - 48 + carryBit);
            else if(curB < 0)
                tmp = (a.charAt(curA--) - 48 + carryBit);
            else{
                tmp = a.charAt(curA--) + b.charAt(curB--) - 96 + carryBit;
            }
            carryBit = tmp / 2; // 更新进位
            ans = (tmp % 2) + ans; // 将这一轮的运算的结果加到前面
        }
        // 当 a 和 b 所有位都遍历完了后,还需要查看是否有进位,如果有进位这需要将进位加上。
        if(carryBit == 1) ans = carryBit + ans;
        return ans;
    }
}

3.给定一个非负整数 n ,请计算 0 到 n 之间的每个数字的二进制表示中 1 的个数,并输出一个数组。

class Solution {
    public int[] countBits(int n) {
        int[] ans = new int[n + 1];
        for(int i = 1; i <= n; i++){
            // 如果当前num为偶数,则二进制中1的个数为 num/2 的二进制中1的个数。
            if(i % 2 == 0)
                ans[i] = ans[i/2];
            // 如果当前num为奇数,则二进制中1的个数为前一个数二进制1的个数+1。
            else
                ans[i] = ans[i-1] + 1;
        }
        return ans;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值