携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情
二进制求和
给你两个二进制字符串,返回它们的和(用二进制表示)。
输入为 非空 字符串且只包含数字 1 和 0。
- 示例 1:
输入: a = "11", b = "1"
输出: "100"
- 示例 2:
输入: a = "1010", b = "1011"
输出: "10101"
提示:
每个字符串仅由字符 '0' 或 '1' 组成。
1 <= a.length, b.length <= 10^4
字符串如果不是 "0" ,就都不含前导零。
方法一:模拟法(Java)
我们可以借鉴列竖式的方法,末尾对齐,逐位相加。在十进制的计算中逢十进一,二进制中我们需要逢二进一。
注意,为了让各个位置对齐,你可以先反转这个代表二进制数字的字符串,然后低下标对应低位,高下标对应高位。
当然你也可以直接把 a 和 b 中短的那一个补 0 直到和长的那个一样长,然后从高位向低位遍历,对应位置的答案按照顺序存入答案字符串内,最终将答案串反转。
class Solution {
public String addBinary(String a, String b) {
StringBuffer ans = new StringBuffer();
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();
}
}
时间复杂度:O(N)
空间复杂度:O(1)
方法二:模拟(Go)
具体方法已经在上文中表述,详情请看上文。
主要是需要先补零,保证长度一致,再采用逢二进一的思路,就好了!注意运行到最后一次,判断是否需要进位!即可
func addBinary(a string, b string) string {
res := ""
carry := 0
l1, l2 := len(a) - 1, len(b) - 1
for l1 >= 0 || l2 >= 0 {
x, y := 0, 0
if l1 >= 0 {
x = int(a[l1] - byte('0'))
}
if l2 >= 0 {
y = int(b[l2] - byte('0'))
}
sum := x + y + carry
res += strconv.Itoa(sum % 2)
carry = sum / 2
l1--
l2--
}
if carry != 0 {
res += strconv.Itoa(carry)
}
return reverseString(res)
}
func reverseString(str string) string {
temp := []byte(str)
left, right := 0, len(temp) - 1
for left < right {
temp[left], temp[right] = temp[right], temp[left]
left++
right--
}
return string(temp)
}
时间复杂度:O(N)
空间复杂度:O(1)