剑指 Offer II 002. 二进制加法【暴力】【模拟】
题目
给定两个 01 字符串 a
和 b
,请计算它们的和,并以二进制字符串的形式输出。
输入为 非空 字符串且只包含数字 1
和 0
。
难度:简单
提示:
1 <= a.length, b.length <= 104
a
和b
仅由字符'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)