「这是我参与11月更文挑战的第15天,活动详情查看:2021最后一次更文挑战」
题目
给你两个二进制字符串,返回它们的和(用二进制表示)。
输入为 非空 字符串且只包含数字 1 和 0。
示例 1:
输入: a = "11", b = "1"
输出: "100"
示例 2:
输入: a = "1010", b = "1011"
输出: "10101"
提示:
- 每个字符串仅由字符 '0' 或 '1' 组成。
- 1 <= a.length, b.length <= 10^4
- 字符串如果不是 "0" ,就都不含前导零。
解题思路
方法一:不用加法的二进制求和
- a & b 的结果,左移一位(<< 1)就得到进位数
- a ^ b ,异或,其实就是不带进位的加法,结果更新给 a
- 求出得到进位数,更新给 b
/**
* @param {string} a
* @param {string} b
* @return {string}
*/
const addBinary = (a, b) => {
a = parseInt(a, 2);
b = parseInt(b, 2);
while (b != 0) {
let carry = a & b;
a = a ^ b;
b = carry << 1;
}
return a.toString(2);
};
但是很可惜,我们提交代码之后会发现并不可行。原因是JavaScript中的 parseInt 在将很大的二进制转十进制时会溢出。如下👇:
方法二:逐位相加
- 先让 a 和 b 对齐,补齐前面的0
- 从右往左,逐位相加,用 carry 变量记录是否 进1
- 每一位的计算结果放到 res 数组里,最后转成字符串
/**
* @param {string} a
* @param {string} b
* @return {string}
*/
const addBinary = (a, b) => {
while (a.length > b.length) b = '0' + b;
// 先对齐
while (a.length < b.length) a = '0' + a;
let res = new Array(a.length);
let sum = 0;
// 进位
let carry = 0;
for (let i = a.length - 1; i >= 0; i--) {
sum = Number(a[i]) + Number(b[i]) + carry;
if (sum >= 2) {
res[i] = sum - 2;
carry = 1;
} else {
res[i] = sum;
carry = 0;
}
}
if (carry) res.unshift(1); // 循环结束还要进1,则在res数组前端加一个1
return res.join('');
};
方法三:将上面方法根据位运算改进一下
- 当前位不带进位相加的结果是异或求出的
- 当前位AND得出当前位的进位,考虑上之前的进位,算出给下一轮迭代的进位
/**
* @param {string} a
* @param {string} b
* @return {string}
*/
const addBinary = (a, b) => {
while (a.length > b.length) b = '0' + b;
while (a.length < b.length) a = '0' + a;
let res = new Array(a.length);
let val; // 当前位不进位的相加结果
let carry; // 当前位的进位
let carryFromBefore = 0; // 当前相加是否有来自上一位的进1
for (let i = a.length - 1; i >= 0; i--) {
val = Number(a[i]) ^ Number(b[i]); // 异或是不带进位的相加
carry = Number(a[i]) & Number(b[i]); // 求出当前位的进位
if (carryFromBefore) { // 有来自上一位的进位
if (val == 0) {
val = 1; // 加上进位 变为1
} else { // 当前位1 + 进位1 = 2
carry = 1; // 往前进1
val = 0; // 当前位为0
}
}
carryFromBefore = carry; // 给下一轮迭代使用的进位
res.unshift(val); // 从res数组的前头推入
}
if (carry) res.unshift(1); // 循环结束,还有进位,就要多加1
return res.join('');
};
结束语
这里是小葵🌻,只要把心朝着太阳的地方,就会有温暖~
让我们一起来攻克算法难关吧!!