问题描述
小U和小R喜欢探索二进制数字的奥秘。他们想找到一个方法,将两个二进制字符串相加并以十进制的形式呈现。这个过程需要注意的是,他们的二进制串可能非常长,所以常规的方法可能无法处理大数。小U和小R希望你帮助他们设计一个算法,该算法能在保证时间复杂度不超过O(n^2)的前提下,返回两个二进制字符串的十进制求和结果。
输入:binary1 = "101" ,binary2 = "110"
输出:'11'
思路分析
问题理解
结合豆包的提示,需要将两个二进制字符串相加,并将结果以十进制的形式返回。由于二进制字符串可能非常长,常规的方法可能无法处理大数,因此我们需要设计一个高效的算法。
数据结构选择
- 使用列表
s来存储每一位的和,这样可以方便地处理进位。 - 使用变量
t来存储进位。
算法步骤
-
初始化:
- 创建一个空列表
s用于存储每一位的和。 - 初始化进位变量
t为 0。
- 创建一个空列表
-
反向遍历两个二进制字符串:
- 从两个字符串的末尾开始遍历,直到两个字符串都遍历完毕。
- 对于每一位,获取当前位的值(如果已经遍历完,则视为 0)。
-
计算当前位的总和:
- 将当前位的值与进位
t相加,得到当前位的总和。 - 根据总和的值,决定当前位的值和进位
t。
- 将当前位的值与进位
-
处理进位:
- 如果遍历结束后仍有进位,将其添加到结果列表
s中。
- 如果遍历结束后仍有进位,将其添加到结果列表
-
计算结果的十进制值:
- 将结果列表
s转换为十进制数。
- 将结果列表
时间复杂度
- 该算法的时间复杂度为
O(n),其中n是两个二进制字符串中较长的那个的长度。这符合题目要求的时间复杂度不超过O(n^2)的限制。
优化
在豆包的提示下,
-
初始化:
- 创建一个变量
result用于存储最终的十进制结果。 - 初始化进位变量
t为 0。
- 创建一个变量
-
反向遍历两个二进制字符串:
- 从两个字符串的末尾开始遍历,直到两个字符串都遍历完毕。
- 对于每一位,获取当前位的值(如果已经遍历完,则视为 0)。
-
计算当前位的总和:
- 将当前位的值与进位
t相加,得到当前位的总和。 - 根据总和的值,决定当前位的值和进位
t。 - 直接将当前位的值累加到
result中。
- 将当前位的值与进位
-
处理进位:
- 如果遍历结束后仍有进位,将其累加到
result中。
- 如果遍历结束后仍有进位,将其累加到
def solution(binary1, binary2):
s = []
t = 0
# 反向遍历两个二进制字符串
i, j = len(binary1) - 1, len(binary2) - 1
while i >= 0 or j >= 0:
a = int(binary1[i]) if i >= 0 else 0
b = int(binary2[j]) if j >= 0 else 0
total = a + b + t # 计算当前位的总和
if total == 3:
s.append(1)
t = 1
elif total == 2:
s.append(0)
t = 1
elif total == 1:
s.append(1)
t = 0
else:
s.append(0)
t = 0
i -= 1
j -= 1
if t > 0:
s.append(1) # 如果有进位需要添加
# 计算结果的十进制值
ans = 0
for idx in range(len(s)):
ans += s[idx] * (2 ** idx) # 计算每一位的值
return str(ans)
if __name__ == "__main__":
# You can add more test cases here
print(solution("101", "110") == "11")
print(solution("111111", "10100") == "83")
print(solution("111010101001001011", "100010101001") == "242420")
print(solution("111010101001011", "10010101001") == "31220")