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

27 阅读5分钟

问题描述

小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'

解题思路

要解决这个问题,我们需要设计一个算法来将两个二进制字符串相加,并将结果转换为十进制形式。由于二进制字符串可能非常长,我们需要确保算法的时间复杂度不超过 O(n^2)。以下是详细的解题思路:

1. 理解问题

  • 输入:两个二进制字符串 binary1binary2
  • 输出:两个二进制字符串相加后的十进制结果。

2. 数据结构选择

  • 使用字符串来表示二进制数,因为二进制数可能非常大,无法直接用整数类型处理。

3. 算法步骤

  1. 对齐二进制字符串

    • 找到两个二进制字符串的最大长度。
    • 在较短的字符串前面补0,使得两个字符串长度相等。
  2. 逐位相加

    • 从右到左逐位相加,同时考虑进位。
    • 如果当前位的和大于等于2,则需要进位。
  3. 处理进位

    • 如果最高位相加后有进位,需要在结果的最前面加上进位。
  4. 转换为十进制

    • 将最终的二进制结果转换为十进制字符串。

4. 时间复杂度分析

  • 对齐字符串:O(n),其中 n 是字符串的最大长度。
  • 逐位相加:O(n)
  • 转换为十进制:O(n)

总的时间复杂度为 O(n),满足题目要求。

5. 空间复杂度分析

  • 主要的空间消耗在于存储结果字符串,空间复杂度为 O(n)

通过以上步骤,我们可以有效地解决这个问题,并且确保时间复杂度不超过 O(n^2)

详细步骤

  1. 对齐字符串

    • 使用 zfill 方法在较短的字符串前面补0,使得两个字符串长度相等。
  2. 逐位相加

    • 从右到左遍历字符串,逐位相加,并记录进位。
    • 如果当前位的和大于等于2,则当前位结果为 total % 2,进位为 total // 2
    • 否则,当前位结果为 total,进位为0。
  3. 处理进位

    • 如果遍历结束后仍有进位,需要在结果的最前面加上进位。
  4. 转换为十进制

    • 将最终的二进制结果字符串转换为十进制字符串。
def solution(binary1, binary2):
    # 找到最长的字符串长度
    max_length = max(len(binary1), len(binary2))
    
    # 在左边补0对齐
    binary1 = binary1.zfill(max_length)
    binary2 = binary2.zfill(max_length)
    
    carry = 0
    result = []
    
    # 从右往左进行相加
    for i in range(max_length - 1, -1, -1):
        b1 = int(binary1[i])
        b2 = int(binary2[i])
        total = b1 + b2 + carry
        
        # 计算当前位的和和进位
        if total >= 2:
            result.append(str(total % 2))
            carry = total // 2
        else:
            result.append(str(total))
            carry = 0
    
    # 如果有进位剩余
    if carry:
        result.append(str(carry))
    
    # 反转结果并转换为十进制字符串
    return str(int(''.join(reversed(result)), 2))
 
if __name__ == "__main__":
    print(solution("101", "110") == "11")
    print(solution("111111", "10100") == "83")
    print(solution("111010101001001011", "100010101001") == "242420")
    print(solution("111010101001011", "10010101001") == "31220")

总结

要解决将两个二进制字符串相加并转换为十进制结果的问题,我们需要设计一个高效的算法,确保时间复杂度不超过 O(n^2)。首先,找到两个二进制字符串的最大长度,并在较短的字符串前面补0,使得两个字符串长度相等。然后,从右到左逐位相加,同时考虑进位。如果当前位的和大于等于2,则需要进位。遍历结束后,如果仍有进位,需要在结果的最前面加上进位。最后,将最终的二进制结果转换为十进制字符串。通过对齐字符串、逐位相加、处理进位和转换为十进制,我们可以确保算法的高效性和正确性。时间复杂度为 O(n),满足题目要求,空间复杂度主要在于存储结果字符串,也为 O(n)。通过这些步骤,我们成功地将两个二进制字符串相加并转换为十进制结果。