持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情
一、题目描述:
67. 二进制求和 - 力扣(LeetCode) (leetcode-cn.com)
给你两个二进制字符串,返回它们的和(用二进制表示)。
输入为 非空 字符串且只包含数字 1 和 0。
示例 1:
输入: a = "11", b = "1"
输出: "100"
示例 2:
输入: a = "1010", b = "1011"
输出: "10101"
提示:
- 每个字符串仅由字符 '0' 或 '1' 组成。
- 1 <= a.length, b.length <= 10^4
- 字符串如果不是 "0" ,就都不含前导零。
二、思路分析:
因为 js 的精度比较小,所以官方的模拟和位运算方法都不适合 js,数值较大时结果会出错。 又因为 js 的字符串的值不能改动,所以空间复杂度不可能为 o(1)。 用 res 栈保存结果,用 carry 代表进位,初始化为 0: 初始化 i = a.length-1, j = b.length-1 ,同时遍历 a 和 b 字符串:
- 当 carry、a[i]、b[j]中只有 1 个 1 或均为 1 时,res 该位置为 1,即 carry ^ a[i] ^ b[j] 为 1;
- 当 carry、a[i]、b[j]中有 2 个 1 或均为 0 时,res 该位置为 0,即 carry ^ a[i] ^ b[j] 为 0;
- 当 carry、a[i]、b[j]中存在大于 2 个 1 时需要进位,即三者之和大于等于 2。 i < 0 或 j < 0 时跳出循环。
对多出来的那一部分进行遍历进位即可,假设 a 长度比较长:
- a[i]、carry 异或结果就是 res 该位置的值;
- a[i]、carry 与结果就是下一次进位的值。
三、AC 代码:
var addBinary = function(a, b) {
let carry = 0;
let res = [];
let i = a.length-1, j = b.length-1;
for(; i >= 0 && j >= 0; i--, j--) {
res.unshift(carry ^ a[i] ^ b[j]);
carry = (carry+parseInt(a[i])+parseInt(b[j])) >= 2 ? 1 : 0;
}
while(i >= 0) {
res.unshift(a[i] ^ carry);
carry = a[i] & carry;
i--;
}
while(j >= 0) {
res.unshift(b[j] ^ carry);
carry = b[j] & carry;
j--;
}
if(carry) { res.unshift(1); }
return res.join("");
};
范文参考:
C语言,模拟高精度加法【适用多种情况】 - 二进制求和 - 力扣(LeetCode)
Java解题:时间复杂度(max(a.length ,b.length)),空间复杂度(1) - 二进制求和 - 力扣(LeetCode)