LeetCode 67. 二进制求和 | Python

2020-06-23  本文已影响0人  大梦三千秋

67. 二进制求和


题目来源:力扣(LeetCode)https://leetcode-cn.com/problems/add-binary

题目


给你两个二进制字符串,返回它们的和(用二进制表示)。

输入为 非空 字符串且只包含数字 1 和 0。

示例 1:

输入: a = "11", b = "1"
输出: "100"

示例 2:

输入: a = "1010", b = "1011"
输出: "10101"

提示:

解题思路


思路:位运算

题目提示中说明,如果字符串不是 “0”,那么都不含前导零。在这里先用普通的加法来尝试解决问题,由于这个前提,在进行加法运算的时候,需要先将字符进行补位,然后逐位相加。

这个方法的具体步骤如下:

关于这个方法的代码大致如下:

def addBinary(self, a: str, b: str) -> str:
    while len(a) > len(b):
        b = '0' + b
    while len(a) < len(b):
        a = '0' + a

    ans = [0] * len(a)

    # 记录逐位相加的结果,
    # 判断是否有进位
    add_res = 0
    carry = 0

    for i in range(len(a)-1, -1, -1):
        add_res = int(a[i]) + int(b[i]) + carry
        # 字符只包含 1 和 0
        # 不包含进位,相加结果最大为 2
        # 包含进位,可能为 3
        if add_res >= 2:
            carry = 1
            # 逢 2 进位,当前位置的元素则为 add_res - 2
            ans[i] = str(add_res - 2)
        else:
            carry = 0
            ans[i] = str(add_res)

    # 最后还需要再次确认,最终的运算中是否有进位
    return ''.join(['1'] + ans) if carry else ''.join(ans)

这段代码使用的普通加法进行解决问题。下面尝试不用加减法来解决问题,这里涉及的就是位运算

这里再提及下,按位与异或 运算。

按位与 运算:是指参与运算的两数对应二进制相与。运算的规则是,当对应的进制位都为 1 时,结果才为 1,否则都为 0。

异或 运算:也叫半加运算,因为它的运算法则相当于不带进位的二进制加法。例如:

可以看出,异或运算法则与加法法则相同,但是不带进位。

回到当前的题目,我们现在要用位运算来模拟加法求出结果。现在我们拆解一下,先进行 异或 运算,求得无进位结果。根据 按位与,同为 1,结果位才是 1 的运算规则,可以求得进位。循环运算,直到最终进位为 0 时,也就能得到结果。

具体的算法设计如下:

具体的代码实现如下。

代码实现


class Solution:
    def addBinary(self, a: str, b: str) -> str:
        # 转换为整数型数值
        m, n = int(a, 2), int(b, 2)

        # n 在循环中存储进位
        # 当进位为 0,循环结束
        while n:
            # 异或计算无进位相加结果
            ans = m ^ n
            # 计算进位
            # 进位应该在更高一位,所以需要左移
            carry = (m & n) << 1
            # 重置 m,n;此时 m 存储结果,n 存储进位
            m = ans
            n = carry
        # m 存储结果,当 n 为 0,表示无进位
        # 循环结束,返回 m 的二进制形式
        # 注意转换成二进制形式的前缀 '0b'
        return bin(m)[2:]

实现结果


实现结果

总结


上一篇 下一篇

猜你喜欢

热点阅读