文章目录

  • 67. 二进制求和:
  • 样例 1:
  • 样例 2:
  • 提示:
  • 分析:
  • 题解:
  • rust:
  • go:
  • c++:
  • python:
  • java:



67. 二进制求和:

给你两个二进制字符串 a 和 b ,以二进制字符串的形式返回它们的和。

样例 1:

输入:

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

	"100"

样例 2:

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

提示:

  • 1 <= a.length, b.length <= 104
  • ab 仅由字符 '0''1' 组成
  • 字符串如果不是 "0" ,就不含前导零

分析:

  • 面对这道算法题目,二当家的再次陷入了沉思。
  • 直接用API将字符串按照2进制转成整型,相加,然后再按照2进制转成字符串,打完收功,但是这种方式有可能会导致整形溢出。
  • 按照字符的方式逆向逐个处理,模拟我们手算的方式,一位一位的计算,满二进一,余数就是当前位,这种方式代码量比较大,但是不会整形溢出。需要注意的是两个数位遍历完,还要再将最后有可能的进位加进去。由于计算是按位计算,从末位开始,而结果要的是字符串,如果我们每次都将结果拼在后面,这种情况下末位相加的结果会在开头,是反向的,所以最后还需要将结果字符串反转,当然也可以每次都把按位相加的结果放在字符串的头部,这样就不需要最后再反转结果。
  • 另外还可以使用位运算,两个二进制位只有其中一个是 '0' 另外一个是 '1' 的情况下,本位才会是 '1' ,所以可以使用位异或运算得到本位的值。而只有两个位都是 '1' 的情况下才会进位,所以可以使用位与运算得到进位的值,不会无休止的进位,最终也可以得到结果,这样可以不使用加法运算而计算出两数相加的结果。

题解:

rust:

impl Solution {
    pub fn add_binary(a: String, b: String) -> String {
		let mut ans = String::new();

        let mut carry = 0;

        (0..a.len().max(b.len())).for_each(|i| {
            if i < a.len() && a.as_bytes()[a.len() - 1 - i] == b'1' {
                carry += 1;
            }
            if i < b.len() && b.as_bytes()[b.len() - 1 - i] == b'1' {
                carry += 1;
            }
            if carry == 1 || carry == 3 {
                ans.push('1');
            } else {
                ans.push('0');
            }
            carry /= 2;
        });

        if carry > 0 {
            ans.push('1');
        }

        return ans.chars().rev().collect();
    }
}

go:

func addBinary(a string, b string) string {
	ans := ""
	carry := 0
	lenA, lenB := len(a), len(b)
	n := lenA
	if lenB > lenA {
		n = lenB
	}

	for i := 0; i < n; i++ {
		if i < lenA {
			carry += int(a[lenA-i-1] - '0')
		}
		if i < lenB {
			carry += int(b[lenB-i-1] - '0')
		}
		ans = strconv.Itoa(carry%2) + ans
		carry /= 2
	}
	if carry > 0 {
		ans = "1" + ans
	}

	return ans
}

c++:

class Solution {
public:
    string addBinary(string a, string b) {
		string ans;
        reverse(a.begin(), a.end());
        reverse(b.begin(), b.end());

        int n = max(a.size(), b.size()), carry = 0;
        for (size_t i = 0; i < n; ++i) {
            carry += i < a.size() ? (a.at(i) == '1') : 0;
            carry += i < b.size() ? (b.at(i) == '1') : 0;
            ans.push_back((carry % 2) ? '1' : '0');
            carry /= 2;
        }

        if (carry) {
            ans.push_back('1');
        }
        reverse(ans.begin(), ans.end());

        return ans;
    }
};

python:

class Solution:
    def addBinary(self, a: str, b: str) -> str:
        x, y = int(a, 2), int(b, 2)
        while y:
            answer = x ^ y
            carry = (x & y) << 1
            x, y = answer, carry
        return bin(x)[2:]

java:

class Solution {
    public String addBinary(String a, String b) {
		StringBuilder ans = new StringBuilder();

        int n = Math.max(a.length(), b.length()), carry = 0;
        for (int i = 0; i < n; ++i) {
            carry += i < a.length() ? (a.charAt(a.length() - 1 - i) - '0') : 0;
            carry += i < b.length() ? (b.charAt(b.length() - 1 - i) - '0') : 0;
            ans.append((char) (carry % 2 + '0'));
            carry /= 2;
        }
        if (carry > 0) {
            ans.append('1');
        }
        ans.reverse();

        return ans.toString();
    }
}