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

49 阅读5分钟

问题描述

将两个二进制字符串相加,并以十进制形式返回求和结果。由于二进制字符串可能非常长,不能直接转换为十进制求和。因此,需要设计一个时间复杂度不超过 (O(n^2)) 的算法来处理大数二进制字符串相加,并输出十进制的和。

问题分析

这道题的关键在于如何处理二进制数的大数相加问题。我们可以将二进制字符串逐位模拟相加,计算出二进制结果后,再将该二进制字符串转换为十进制数。这一过程可以分为以下几个步骤:

  1. 二进制字符串对齐:将两个输入字符串通过补零对齐,使得二进制长度一致,便于逐位相加。
  2. 逐位相加:从低位到高位逐位相加。
  3. 进位处理:逐位相加时,记录进位,并保存下来并用于下次加法操作。
  4. 二进制转十进制:将得到的相加结果(仍是一个二进制字符串)转换成十进制数。

解题思路

solution

主函数,负责将两个二进制字符串相加并返回十进制结果。具体操作包括:

  1. 字符串补零对齐:获取两个二进制字符串的长度,将较短的字符串用 zfill 补零,使其与较长字符串等长,从而便于逐位相加。
  2. 逐位调用 plus 函数相加:从最低位开始(从右至左),逐位调用 plus 函数来对当前位及进位进行加和,结果保存在 sum 列表中。
  3. 记录进位plus 函数返回当前位的和与进位,进位用于下一个更高位的加法计算,最终的最高位进位也会记录在 sum 列表中。
  4. 调用 binary_decimal 函数转换十进制:最终计算完成的二进制结果保存在 sum 中,调用 binary_decimal 函数将 sum 转换为十进制数并返回。

binary_decimal

binary_decimal 函数将二进制字符串转换为十进制,主要使用指数乘法的原理逐位相加完成转换。具体操作包括:

  1. 从最高位到最低位遍历二进制字符串。
  2. 对于每一位,如果该位是 '1',则将其按位权值(对应的 (2^{位置}))乘积加入 sum 中。
  3. 最终得到的 sum 即为该二进制字符串对应的十进制值。

plus

plus 函数执行逐位加和操作,并根据加和结果计算当前位的值和进位。具体流程如下:

  1. 将二进制位 c1c2 和进位 add 转换为整数后求和,结果存储在 sum 中。
  2. 根据 sum 的值来判断返回结果:
    • sum == 3 时,当前位为 '1',进位为 '1'
    • sum == 2 时,当前位为 '0',进位为 '1'
    • sum == 1 时,当前位为 '1',无进位。
    • sum == 0 时,当前位为 '0',无进位。
  3. 返回当前位的计算结果和进位,用于下一位的加和。

代码实现

import math

def solution(binary1, binary2):
    max_len = max(len(binary1), len(binary2))
    # 对齐二进制字符串长度
    binary1 = binary1.zfill(max_len)
    binary2 = binary2.zfill(max_len)
    
    # 初始化结果列表,用于存储相加结果
    sum = ['0'] * (max_len + 1)
    add = '0'
    
    # 从最低位向高位逐位相加
    for i in range(max_len - 1, -1, -1):
        c1 = binary1[i]
        c2 = binary2[i]
        # plus 函数计算当前位结果与进位
        sum[i + 1], add = plus(c1, c2, add)
    
    # 将最终进位放入结果的最高位
    sum[0] = add
    
    # 将二进制结果转换为十进制
    result = binary_decimal(sum)
    return str(result)

def binary_decimal(string):
    # 将二进制字符串转十进制
    sum = 0
    for i in range(len(string)):
        alpha = len(string) - i - 1
        if string[i] == '1':
            sum += math.pow(2, alpha)
    return int(sum)

def plus(c1, c2, add):
    # 将字符转换为整数以便相加
    c1, c2, add = int(c1), int(c2), int(add)
    # 三数相加判断结果和进位
    sum = c1 + c2 + add
    if sum == 3:
        return '1', '1'  # 当前位为1,进位为1
    elif sum == 2:
        return '0', '1'  # 当前位为0,进位为1
    elif sum == 1:
        return '1', '0'  # 当前位为1,无进位
    else:
        return '0', '0'  # 当前位为0,无进位

复杂度分析

  • 时间复杂度:在 solution 函数中,字符串对齐、逐位相加和二进制转十进制的步骤都为 (O(n)) 复杂度,其中 (n) 是较长的二进制字符串的长度。因此,总体时间复杂度为 (O(n))。
  • 空间复杂度:由于需要存储与输入字符串等长的结果列表,因此空间复杂度为 (O(n))。

可优化方向

  1. 二进制转十进制binary_decimal 函数中使用幂运算来计算每个位的权重值。可以通过左移操作实现从二进制到十进制的直接转换,从而提高效率。
  2. 进位优化:在 plus 函数中,根据不同情况下的三位相加,直接返回进位结果的逻辑可以优化为字典查表方式,减少条件判断的分支开销。

总结与收获

本题通过模拟二进制字符串的逐位相加,解决了大数二进制相加的问题。笔记中对逐位相加、进位和二进制转十进制等操作进行了详细解释,帮助理解大数处理方法。通过题解学习了如何有效地对齐和遍历字符串,利用数学操作将二进制转十进制并输出结果。