二进制之和 | 豆包MarsCode AI刷题

86 阅读6分钟

1. 题目

二进制之和

问题描述

小U和小R喜欢探索二进制数字的奥秘。他们想找到一个方法,将两个二进制字符串相加并以十进制的形式呈现。这个过程需要注意的是,他们的二进制串可能非常长,所以常规的方法可能无法处理大数。小U和小R希望你帮助他们设计一个算法,该算法能在保证时间复杂度不超过O(n^2)的前提下,返回两个二进制字符串的十进制求和结果。


测试样例

样例1:

输入:binary1 = "101" ,binary2 = "110"
输出:'11'

样例2:

输入:binary1 = "111111" ,binary2 = "10100"
输出:'83'

样例3:

输入:binary1 = "111010101001001011" ,binary2 = "100010101001"
输出:'242420'

样例4:

输入:binary1 = "111010101001011" ,binary2 = "10010101001"
输出:'31220'

样例5:

输入:binary1 = "11" ,binary2 = "1"
输出:'4'

2. 解题思路

问题理解

我们需要将两个二进制字符串相加,并将结果以十进制的形式返回。由于二进制字符串可能非常长,常规的整数类型可能无法处理,因此我们需要设计一个算法来处理大数。

数据结构选择

我们可以使用字符串来表示二进制数,因为字符串可以处理任意长度的数据。

问题分析

在进行二进制加法时,我们必须注意以下几个方面:

  1. 输入格式:输入是两个二进制字符串,可能存在不同的长度。对于这种情况,我们需要对较短的字符串进行补零操作,以使其长度与较长的字符串一致。
  2. 逐位相加:与十进制加法类似,我们需要从字符串的末尾开始逐位相加。每一位的和可能会产生进位,因此需要考虑将进位添加到下一位的和中。
  3. 进位处理:在二进制中,只能产生进位值为0或1。若当前位的和大于或等于2,则需要将1进位到下一位。
  4. 最终结果转换:计算完所有位的和,并处理完所有进位后,最终的结果是一个二进制字符串。根据题目要求,我们需要将其转换为十进制形式输出。

算法步骤

  1. 补齐长度:首先,我们需要确保两个二进制字符串的长度相同。如果长度不同,可以在较短的字符串前面补0。
  2. 逐位相加:从最低位(字符串的最后一位)开始,逐位相加,并考虑进位。
  3. 处理进位:如果某一位的和大于1,则需要进位。
  4. 转换为十进制:将最终的二进制结果转换为十进制。

伪代码

function solution(binary1, binary2):
    // 补齐长度
    while binary1.length < binary2.length:
        binary1 = '0' + binary1
    while binary2.length < binary1.length:
        binary2 = '0' + binary2
    carry = 0
    result = ""
    // 从最低位开始逐位相加
    for i from binary1.length - 1 to 0:
        sum = (binary1[i] - '0') + (binary2[i] - '0') + carry
        carry = sum // 2  // 计算进位
        result = (sum % 2) + result  // 当前位的结果
    // 如果最后还有进位,需要加到结果的最前面
    if carry > 0:
        result = '1' + result
    // 将二进制结果转换为十进制
    return binaryToDecimal(result)
function binaryToDecimal(binary):
    // 将二进制字符串转换为十进制整数
    return parseInt(binary, 2).toString()

3. 代码实现

function solution(binary1, binary2) {
  // 补齐长度
  while (binary1.length < binary2.length) {
    binary1 = '0' + binary1;
  }
  while (binary2.length < binary1.length) {
    binary2 = '0' + binary2;
  }
  
  let carry = 0;
  let result = "";
  
  // 从最低位开始逐位相加
  for (let i = binary1.length - 1; i >= 0; i--) {
    let sum = (binary1[i] - '0') + (binary2[i] - '0') + carry;
    carry = Math.floor(sum / 2);  // 计算进位
    result = (sum % 2) + result;  // 当前位的结果
  }
  
  // 如果最后还有进位,需要加到结果的最前面
  if (carry > 0) {
    result = '1' + result;
  }
  
  // 将二进制结果转换为十进制
  return binaryToDecimal(result);
}

function binaryToDecimal(binary) {
  // 将二进制字符串转换为十进制整数
  return parseInt(binary, 2).toString();
}

function main() {
  // You can add more test cases here
  console.log(solution("101", "110") === "11");
  console.log(solution("111111", "10100") === "83");
  console.log(solution("111010101001001011", "100010101001") === "242420");
  console.log(solution("111010101001011", "10010101001") === "31220");
}

main();

使用 js 内置类型 BigInt

function solution(binary1, binary2) {
    // 使用BigInt来处理大数加法
    const num1 = BigInt(`0b${binary1}`); // 将二进制字符串转换为BigInt
    const num2 = BigInt(`0b${binary2}`); // 将二进制字符串转换为BigInt
    const sum = num1 + num2; // 计算和
    return sum.toString(); // 将结果转换为字符串并返回
}

// 测试用例
console.log(solution("101", "110") === "11");
console.log(solution("111111", "10100") === "83");
console.log(solution("111010101001001011", "100010101001") === "242420");
console.log(solution("111010101001011", "10010101001") === "31220");

4. 收获

  1. binary1[i] - '0'这是 ascll 码计算;作用和 parseInt(binary1[i])一致
  2. parseInt(str,2)将字符串转换为整数,第二个参数指定了第一个参数(字符串)的基数(或称为进制)
  3. num.toString()将十进制整数转换为二进制字符串,第二个参数为将要转换为的字符串的基数(或称为进制)

python 提交版本完整代码:

def solution(binary1, binary2):
    # 补齐长度
    while len(binary1) < len(binary2):
        binary1 = '0' + binary1
    while len(binary2) < len(binary1):
        binary2 = '0' + binary2

    carry = 0
    result = []

    # 从最低位开始逐位相加
    for i in range(len(binary1) - 1, -1, -1):
        sum = (int(binary1[i]) - int('0')) + (int(binary2[i]) - int('0')) + carry
        carry = sum // 2  # 计算进位
        result.append(sum % 2)  # 当前位的结果

    # 如果最后还有进位,需要加到结果的最前面
    if carry > 0:
        result.append(1)

    # 反转结果并将其转为字符串
    result.reverse()
    binary_result = ''.join(map(str, result))

    # 将二进制结果转换为十进制
    return binary_to_decimal(binary_result)

def binary_to_decimal(binary):
    # 将二进制字符串转换为十进制整数
    return str(int(binary, 2))

if __name__ == "__main__":
    # 测试用例
    print(solution("101", "110") == "11")
    print(solution("111111", "10100") == "83")
    print(solution("111010101001001011", "100010101001") == "242420")
    print(solution("111010101001011", "10010101001") == "31220")