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

114 阅读3分钟

题目分析

这道题目要求我们将两个二进制字符串相加,并返回十进制形式的求和结果。由于二进制字符串可能非常长,普通的整型运算可能会因溢出而失败,因此我选择通过字符串逐位处理来完成运算.

关键点:

  1. 逐位相加:从字符串的低位(右端)开始逐位相加,模拟人类做加法的方式
  2. 进位处理:每次加法可能产生进位(carry),需要记录并在下一位继续处理
  3. 结果反转:由于从低位开始计算,最后得到的结果需要反转
  4. 十进制转换:最后将二进制结果转化为十进制数

解题思路

我将代码分为以下几个部分:

  1. 初始化变量:

    • result: 存储二进制加法的中间结果
    • carry: 记录进位值
    • i, j: 分别指向两个二进制字符串的末尾,用于逐位遍历
  2. 逐位相加:

    • 使用 while 循环,条件是 i >= 0j >= 0carry 不为零
    • 从两个字符串取当前位的值(若索引超出范围,则取 0)
    • 计算当前位总和 total = bit1 + bit2 + carry
    • 当前位的结果为 total % 2,记录在 result
    • 更新进位值 carry = total // 2
  3. 结果反转并转化为十进制:

    • 反转 result 并拼接成字符串
    • 使用 int(binary_result, 2) 转换为十进制数
  4. 返回结果

    • 将十进制数转换为字符串返回

复杂度分析

  1. 时间复杂度

    • while 循环中,遍历了两个字符串的长度,复杂度为 O(max⁡(n,m)),其中 nnn 和 mmm 分别是两个二进制字符串的长度
    • 二进制字符串转换为十进制数时,复杂度为 O(k),其中 k 是结果的长度
    • 总时间复杂度约为 O(n+k),通常 k≤n+mk \leq n + m,因此最终时间复杂度为 O(n)
  2. 空间复杂度

    • 使用了一个 result 列表来存储二进制结果,空间复杂度为 O(k)

解题难点

在解题过程中,我觉得对于我这个初学者来说,理解如何正确管理 carry 并在多次循环中保持正确性会有点难。在解决结果反转与十进制转换时候我也遇到了一些问题。我觉得反转列表后正确转换为字符串比较繁琐,也不太熟悉如何将二进制转为十进制可,尤其是使用 int(binary_result, 2).

代码示例

def solution(binary1, binary2):
    # 初始化变量
    result = []
    carry = 0
    i, j = len(binary1) - 1, len(binary2) - 1

    # 逐位相加
    while i >= 0 or j >= 0 or carry:
        bit1 = int(binary1[i]) if i >= 0 else 0
        bit2 = int(binary2[j]) if j >= 0 else 0
        total = bit1 + bit2 + carry
        result.append(str(total % 2))  # 当前位的二进制值
        carry = total // 2  # 更新进位
        i -= 1
        j -= 1

    # 反转结果并转换为十进制
    result.reverse()
    decimal_result = int(''.join(result), 2)
    return str(decimal_result)

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

刷题总结

通过这道题,我学习到以下知识点:

  1. 字符串如何逐位操作
  2. 使用列表存储中间结果,最后通过 ''.join() 拼接字符串
  3. 理解并实现二进制到十进制的转换
  4. 使用进位逻辑解决类似二进制加法的问题