剑指 Offer II 002. 二进制加法【暴力】【模拟】

题目

给定两个 01 字符串 ab ,请计算它们的和,并以二进制字符串的形式输出。

输入为 非空 字符串且只包含数字 10

难度:简单

提示:

  • 1 <= a.length, b.length <= 104
  • ab 仅由字符 '0''1' 组成
  • 字符串如果不是 "0" ,就不含前导零

注意:本题与主站 67 题相同:https://leetcode-cn.com/problems/add-binary/

题解

暴力

将二进制字符串转换为二进制然后计算即可

class Solution {
    public String addBinary(String a, String b) {
        return Integer.toBinaryString(
                Integer.parseInt(a, 2) + Integer.parseInt(a, 2)
        );
    }
}

复杂度分析

假设a长度为n,b长度为m

  • 时间复杂度:O(N+M)
  • 空间复杂度:UNKOWN

Tip:太长的字符串不能用这个,因为Java中基础数据类型是有范围的,超过了就会报错

模拟

根据题意模拟。使用一个变量carry 表示上一个位置的进位,初始值为 0。记当前位置对其的两个位为ai和bi,则每一位的答案为(carry+ai+bi)mod2,下一位的进位为[carry+ai+bi]/2的下界,因为int类型会自动截掉小数位,所以不需要我们再手动截取。重复上述步骤,直到数字 aa 和 bb 的每一位计算完毕。最后如果carry 的最高位不为 0,则将最高位添加到计算结果的末尾。(来源官方,比纯粹的模拟更棒)

class Solution {
    public String addBinary(String a, String b) {
        // 存储结果
        StringBuffer res = new StringBuffer();
        
        int n = Math.max(a.length(), b.length());
        // 确定进位
        int carry = 0;
        for (int i = 0; i < n; ++i) {
            // 获取carry值,未超过当前串长度则用具体值,超过了补0
            carry += i < a.length() ? (a.charAt(a.length() - 1 - i) - '0') : 0;
            carry += i < b.length() ? (b.charAt(b.length() - 1 - i) - '0') : 0;
            // 算当前位的值,java中char遇到int会向上转型为int
            res.append((char) (carry % 2 + '0'));
            carry /= 2;
        }
        // 如果最后一位算完了carry还是有值,这说明最高位算完了还有值,因为是二进制,所以
        // 只能是1,在最高位补1即可
        if (carry > 0) {
            res.append('1');
        }
        return res.reverse().toString();
    }
}

假设a长度为n,b长度为m,N=Max(n,m)

  • 时间复杂度:O(N)
  • 空间复杂度:O(N)
posted @ 2022-09-18 20:17  tothk  阅读(19)  评论(0编辑  收藏  举报