LeetCode系列记录我学习算法的过程。
携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情
题目
给你两个二进制字符串,返回它们的和(用二进制表示)。
输入为 非空 字符串且只包含数字 1 和 0。
示例:
输入: a = "11", b = "1"
输出: "100"
输入: a = "1010", b = "1011"
输出: "10101"
提示
- 每个字符串仅由字符
'0'或'1'组成。 1 <= a.length, b.length <= 10^4- 字符串如果不是
"0",就都不含前导零。
思路
这个题目也是涉及到进位的问题,可以使用双指针来对两个字符串进行遍历
将对应位的值相加后的值进位后并记录下来
- 定义
p记录当前项是否需要进位,x遍历a,y遍历b,res存储结果 - 从后往前对字符串
a和b进行遍历 - 定义
n记录当前两数组项与进位之和,并移动指针 - 判断
n是否大于1,大于则需要进位,并将当前项赋值为减去2后的值并拼接在res中 - 反之则无需进位,直接将
n拼接到res即可 - 最后遍历完再判断是否还有进位未处理,有则在数组开头插入
1 - 将处理好后的
res返回
代码实现
/**
* @param {string} a
* @param {string} b
* @return {string}
*/
var addBinary = function(a, b) {
let p = false, // 是否需要进位
x = a.length - 1, // 指向 a 的指针
y = b.length - 1, // 指向 b 的指针
res = '' // 结果
// 当 a 和 b 都遍历完则结束循环
while(x >= 0 || y >= 0) {
// n 记录当前两项之和
let n = 0
// 如果 a 当前项存在,则加上该值,并向前移动指针
if (a[x]) {
n += Number(a[x])
x--
}
// b 同上
if (b[y]) {
n += Number(b[y])
y--
}
// 如果当前存在进位,则加一
if (p) n++
// 当 n > 1 时需要进位,保留减 2 之后的值
if (n > 1) {
res = (n - 2) + res
p = true
} else {
// 不需要进位则直接拼接
res = n + res
p = false
}
}
// 最后还有进位则开头拼接 1
if (p) res = '1' + res
// 返回结果
return res
};
优化
还可以将代码进行简化,不需要写太多的 if 判断,从后往前存储结果,最后将结果翻转返回即可
var addBinary = function(a, b) {
let res = "", p = 0
for(let i = a.length - 1, j = b.length - 1; i >= 0 || j >= 0; i--, j--) {
let sum = p
sum += i >= 0 ? parseInt(a[i]) : 0
sum += j >= 0 ? parseInt(b[j]) : 0
res += sum % 2
p = Math.floor(sum / 2)
}
res += p == 1 ? p : ""
// 翻转结果
return res.split('').reverse().join('')
};