前端算法面试必刷题系列[26]

1,191 阅读5分钟

这个系列没啥花头,就是纯 leetcode 题目拆解分析,不求用骚气的一行或者小众取巧解法,而是用清晰的代码和足够简单的思路帮你理清题意。让你在面试中再也不怕算法笔试。

45. 二进制求和 (add-binary)

标签

  • 二进制
  • BigInt

题目

leetcode 传送门

这里不贴题了,leetcode打开就行,题目大意:

给你两个二进制字符串,返回它们的(用二进制表示)。

输入为 非空 字符串且只包含数字 1 和 0。例如

输入: a = "11", b = "1"
输出: "100"
示例 2:

输入: a = "1010", b = "1011"
输出: "10101"

相关知识

1. js 中二进制十进制相互转换

  • 十进制 => 二进制

使用Number.prototype.toString()

语法

numObj.toString([radix]) 参数:radix 指定要用于数字到字符串的转换的基数(从2到36)。如果未指定 radix 参数,则默认值为 10。(默认十进制)

例子

let a = 4
var count = 10;

console.log(count.toString());    // 输出 '10'
console.log((17).toString());     // 输出 '17'
console.log((17.2).toString());   // 输出 '17.2'

var x = 6;

console.log(x.toString(2));       // 输出 '110'
console.log((254).toString(16));  // 输出 'fe'

console.log((-10).toString(2));   // 输出 '-1010'
console.log((-0xff).toString(2)); // 输出 '-11111111'
  • 二进制 => 十进制

使用parseInt

语法

parseInt(string, radix);

参数

string

要被解析的值。如果参数不是一个字符串,则将其转换为字符串(使用 ToString 抽象操作)。字符串开头的空白符将会被忽略。 radix (可选) 从 2 到 36,表示字符串的基数。例如指定 16 表示被解析值是十六进制数。请注意,10不是默认值!

如果 radix 是 undefined0未指定的,JavaScript会假定以下情况:

  1. 如果输入的 string以 "0x""0x"(一个0,后面是小写或大写的X)开头,那么radix被假定为16,字符串的其余部分被当做十六进制数去解析。
  2. 如果输入的 string以 "0"(0)开头, radix被假定为8(八进制)10(十进制)。具体选择哪一个radix取决于实现。ECMAScript 5 澄清了应该使用 10 (十进制),但不是所有的浏览器都支持。因此,在使用 parseInt 时,一定要指定一个 radix。
  3. 如果输入的 string 以任何其他值开头, radix 是 10 (十进制)
  4. 如果第一个字符不能转换为数字,parseInt 会返回 NaN

返回值

  1. 从给定的字符串中解析出的一个整数

  2. 或者 NaN,当

    • radix 小于 2 或大于 36
    • 第一个非空格字符不能转换为数字。

例子

parseInt('123', 5) // 38 '123'看作5进制数,返回十进制数38 => 1*5^2 + 2*5^1 + 3*5^0 = 38

2. BigInt

BigInt 是一种特殊的数字类型,它提供了对任意长度整数的支持。

创建 bigint 的方式有两种:

  1. 在一个整数字面量后面加 n
  2. 调用 BigInt 函数,该函数从字符串、数字等中生成 bigint。
const bigint = 1234567890123456789012345678901234567890n;

const sameBigint = BigInt("1234567890123456789012345678901234567890");

const bigintFromNumber = BigInt(10); // 与 10n 相同

基本思路

基本思路有2条

  1. 用按位相加的方式,处理进位
  2. 直接用进制转换方式处理

思路一比较常规,前面有类似问题。我们重点看下思路二

想到直接转十进制相加,再转回二进制,写下了下面的代码,正常情况ok。

var addBinary = function(a, b) {
  a = parseInt(a, 2)
  b = parseInt(b, 2)
  return (a + b).toString(2)
};

let a = '101', b = '1'
console.log(addBinary(a, b))

但是提交leetcode发现超长二进制字符串过不了,才想到js整数位长度限制,于是想用BigInt来处理长整数。 思考 Number 中有个这个二进制转十进制操作 Number('0b11') // 3 同样的BigInt中也可以BigInt('0b100') // 4这样,巧妙地处理了这个问题。

写法实现

var addBinary = function(a, b) {
  a = BigInt("0b" + a);
  b = BigInt("0b"+b);
  return (a + b).toString(2)
};

let a = "10100000100100110110010000010101111011011001101110111111111101000000101111001110001111100001101", 
b = "110101001011101110001111100110001010100001101011101010000011011011001011101111001100000011011110011"
console.log(addBinary(a, b))

另外向大家着重推荐下这位大哥的文章,非常深入浅出,对前端进阶的同学非常有作用,墙裂推荐!!!核心概念和算法拆解系列

今天就到这儿,想跟我一起刷题的小伙伴可以加我微信哦 搜索我的微信号infinity_9368,可以聊天说地 加我暗号 "天王盖地虎" 下一句的英文,验证消息请发给我 presious tower shock the rever monster,我看到就通过,暗号对不上不加哈,加了之后我会尽我所能帮你,但是注意提问方式,建议先看这篇文章:提问的智慧

参考