二进制求和(力扣第67题)
题目:
给你两个二进制字符串,返回它们的和(用二进制表示)。
输入为非空字符串且只包含数字 1
和 0
。
示例1:
输入: a = "11", b = "1" 输出: "100"
示例2:
输入: a = "1010", b = "1011" 输出: "10101"
分析:
其实就是两个二进制数的加法运算,两个二进制数相加,首先设置一个进位标识符flag,初始值设置0。从低位到高位开始相加:
1、对应位置相加,然后再加上flag,三者之和设置为temp_sum,然后结果值的当前位为temp_sum%2,flag = temp_sum/2
2、进行遍历二进制字符串的时候,因为需要从低位开始运算,而二进制数的低位之于字符串对应的位置,是字符串的索引高位,所以解决方法就有两个:
(1)设置两个游标变量,初始值为a、b两个字符串的长度减去1,然后开始遍历,没完成一次,游标变量就自减运算一次
(2)将两个二进制数字符串逆置一下,然后索引低位就和二进制低位对应上了,最后再将结果倒置一下就可以了
3、遍历进行的条件是,a的游标变量的值要在0-a.length这个范围内 或者 b的游标变量的值要在0-b.length这个范围内 或者 flag==1
实现代码1:
public String addBinary(String a, String b) { StringBuilder sa = new StringBuilder(a).reverse(); StringBuilder sb = new StringBuilder(b).reverse(); StringBuilder sc = new StringBuilder(); int i = 0; int flag = 0; while (i < sa.length() && i < sb.length()){ if (sa.charAt(i) == '1' && sb.charAt(i) == '1'){ if (flag == 0){ sc.append(0); }else { sc.append(1); } flag = 1; }else if (sa.charAt(i) == '1' || sb.charAt(i) == '1'){ if (flag == 1){ sc.append(0); flag = 1; }else { sc.append(1); } }else { if (flag == 1){ sc.append(1); }else { sc.append(0); } flag = 0; } i++; } while (i < sa.length()){ if (flag == 1){ if (sa.charAt(i) == '1'){ sc.append(0); flag = 1; }else { sc.append(1); flag = 0; } }else{ if (sa.charAt(i) == '1'){ sc.append(1); }else { sc.append(0); } } i++; } while (i < sb.length()){ if (flag == 1){ if (sb.charAt(i) == '1'){ sc.append(0); flag = 1; }else { sc.append(1); flag = 0; } }else{ if (sb.charAt(i) == '1'){ sc.append(1); }else { sc.append(0); } } i++; } if (flag == 1){ sc.append(1); } return sc.reverse().toString(); }
可以优化一下,上面的代码太麻烦了:
public String addBinary(String a, String b) { int i = a.length() - 1, j = b.length() - 1, carry = 0; StringBuilder str = new StringBuilder(); while (carry == 1 || i >= 0 || j >= 0) { if (i >= 0 && a.charAt(i--) == '1') { carry++; } if (j >= 0 && b.charAt(j--) == '1') { carry++; } str.append(carry % 2); carry /= 2; } return str.reverse().toString(); }
这段代码参考自大神CyC2018。