这是我参与2022首次更文挑战的第23天,活动详情查看:2022首次更文挑战
题目描述
给你提供2个二进制的数(字符串类型),需要你返回它们相加后得到的二进制数。
二进制都是由0或者1组成的。
二进制数相加的规则是
0和1相加等于10和0相加等于01和1相加等于10,需要往前进位。
举个例子:
100 和 011
返回:111
10 和 011
返回:101(相当于010 和 011)
1 和 011
返回:100(相当于001 和 011)
思路分析
第一种方法
因为传入的参数a,b,它们的长度不一定是相等的,所以需要拿到更长的那个。所以可以使用Math.max方法来获取更大的长度len。
拿到len之后,对a,b进行遍历,如果小于len的,对它进行前面补0操作。
这样保证二者的位数都是一样的。
然后需要定义个返回的字符串str,还有个进位状态status(可选值有0,1),默认是0,不进位。
然后我们遍历字符串,从后往前遍历,a字符串和b字符串对应的元素(转成数字类型),还有和进位状态status一起相加。
相加后有四种情况:
-
3, 这种就是1 + 1 + 1,需要把status继续设置为1,然后当前字符串对应的位置也加上1 -
2, 这种就是1 + 0 + 1, 或者1 + 1 + 0,需要把status设置为1,然后当前字符串对应的位置加上0 -
1, 这种就是1 + 0 + 0, 或者0 + 0 + 1,需要把status设置为0,然后当前字符串对应的位置加上1 -
0, 这种就是0 + 0 + 0, 或者0 + 0 + 0,需要把status设置为0,然后当前字符串对应的位置加上0
最后遍历结束的时候需要判断当前的索引是不是第一位,如果是,且status为1,则字符串前面需要再加1(因为进位了)
最后返回字符串即可。
代码如下:
/**
* @param {string} a
* @param {string} b
* @return {string}
*/
var addBinary = function (a, b) {
let str = ''
let status = 0
const len = Math.max(a.length, b.length)
while (len > a.length) {
a = 0 + a
}
while (len > b.length) {
b = 0 + b
}
for (let i = len - 1; i >= 0; i--) {
const sum = +a[i] + +b[i] + status
if (sum === 3) {
str = '1' + str
status = 1
} else if (sum === 2) {
str = '0' + str
status = 1
} else if (sum === 1) {
str = '1' + str
status = 0
} else {
str = '0' + str
status = 0
}
if (i === 0 && status) {
str = '1' + str
}
}
return str
};
耗时如下:
第二种方法
这种方法思路跟第一种方法类似,但是实现起来有点不一样,他是对a和b同时从后往前遍历,如果当前的索引小于0则使用0代替,无需判断最大长度。
然后a,b当前遍历的元素和status相加,它不是跟我分成4种情况判断,而是使用取余和取整,很巧妙。(3,2,1,0四种情况,具体可看第一种方法)
取余赋值给str(3,1 为1, 2,0 为0),取整赋值给status(3,2 为1, 1,0 为0)。
遍历结束后,如果status是1,则需要进位,str 首位加1。
返回字符串即可。
代码如下
/**
* @param {string} a
* @param {string} b
* @return {string}
*/
var addBinary = function (a, b) {
let str = ''
let status = 0
for (let i = a.length - 1, j = b.length - 1; i >= 0 || j >= 0; i--, j--) {
let sum = status
sum += (i >= 0 ? +a[i] : 0)
sum += (j >= 0 ? +b[j] : 0)
str = sum % 2 + str
status = Math.floor(sum / 2)
}
if (status) str = 1 + str
return str
}