给你两个二进制字符串,返回它们的和(用二进制表示)。
输入为 非空 字符串且只包含数字 1 和 0。
示例 1:
输入: a = “11”, b = “1”
输出: “100”
思路:
// 1 1 进位为0 carry=1,该位为0 进位为1 carry=1,该位为1
// 1 0或0 1 进位为0 carry=0 该位为1 进位为1,carry=1,该位为0
// 0 0 进位为0 carry=0 该位为0 进位为1 carry=0 该位为1
首先如果长度不一样时,应该先在左边补零,使长度相等,然后依次判断,如果到最后还有进位,则在最左边的增加一位为1
自己写的代码,努力了
class Solution {
public String addBinary(String a, String b) {
int shortestLen = (a.length() > b.length() ? b.length() : a.length());
if (a.length() > b.length()) {
b = generateZero(a.length() - shortestLen) + b;
} else {
a = generateZero(b.length() - shortestLen) + a;
}
char[] c1=a.toCharArray();
char[] c2=b.toCharArray();
System.out.println(Arrays.toString(c1));
System.out.println(Arrays.toString(c2));
int carry=0;
for(int i=c1.length-1;i>=0;i--){
if(c1[i]=='1'&&c2[i]=='1'){
if(carry==0){
c2[i]='0';
}
else
c2[i]='1';
carry=1;
}
else if(c1[i]=='0'&&c2[i]=='0'){
if(carry==0)
c2[i]='0';
else
c2[i]='1';
carry=0;
}
else{
if(carry==0){
c2[i]='1';
}
else{
c2[i]='0';
carry=1;
}
}
}
StringBuilder stb=new StringBuilder();
if(carry==1){
// c1=new char[c1.length+1];
// c1[0]='1';
// for(int j=1;j<c1.length;j++){
// c1[j]=c2[j-1];
// }
stb.append('1');
//System.out.println(Arrays.toString(c1));
}
for(char c:c2){
stb.append(c);
}
System.out.println(stb);
return stb.toString();
}
public static String generateZero(int n) {
StringBuffer stringBuffer = new StringBuffer();
while (n-- > 0) {
stringBuffer.append("0");
}
return stringBuffer.toString();
}
}
官方题解
思路:
就是将我上述总结的各种情况进行总结,
// 1 1 进位为0 carry=1,该位为0 进位为1 carry=1,该位为1
// 1 0或0 1 进位为0 carry=0 该位为1 进位为1,carry=1,该位为0
// 0 0 进位为0 carry=0 该位为0 进位为1 carry=0 该位为1
也就是说:每一位的答案是(carry+ai+bi)mod2,carry为(carry+ai+bi)/2
class Solution {
public String addBinary(String a, String b) {
int i = a.length() - 1;
int j = b.length() - 1;
int carry = 0;
StringBuilder builder = new StringBuilder();
//循环相加两个字符串相同长度的低位数部分
while (i >= 0 && j >= 0) {
int sum = carry;
sum += a.charAt(i--) - '0';
sum += b.charAt(j--) - '0';
carry = sum / 2;
builder.append(sum % 2);
}
// 如果 a 还没遍历完成(a串比b串长),则继续遍历添加 a 的剩余部分
while (i >= 0) {
int sum = carry + a.charAt(i--) - '0';
carry = sum / 2;
builder.append(sum % 2);
}
// 如果 b 还没遍历完成(b串比a串长),则继续遍历添加 b 的剩余部分
while (j >= 0) {
int sum = carry + b.charAt(j--) - '0';
carry = sum / 2;
builder.append(sum % 2);
}
//如果 carry 不等于0 还有个进位数没加进去,需要补充
if (carry == 1) {
builder.append(carry);
}
//反转字符串获得正常结果
return builder.reverse().toString();
}
官方题解2
思路:整体思路是将两个字符串较短的用 0 补齐,使得两个字符串长度一致,然后从末尾进行遍历计算,得到最终结果。
本题解中大致思路与上述一致,但由于字符串操作原因,不确定最后的结果是否会多出一位进位,所以会有 2 种处理方式:
第一种,在进行计算时直接拼接字符串,会得到一个反向字符,需要最后再进行翻转
第二种,按照位置给结果字符赋值,最后如果有进位,则在前方进行字符串拼接添加进位
class Solution {
public String addBinary(String a, String b) {
String maxStr = a.length() > b.length() ? a : b;
String minStr = a.length() < b.length() ? a : b;
int diff = maxStr.length() - minStr.length();
//如果两个字符串长度不一样,就给字符串长度较小的字符串补0
if (diff > 0){
StringBuilder sb = new StringBuilder();
for (int i = 0; i < diff; i++) {
sb.append("0");
}
sb.append(minStr);
a = maxStr;
b = sb.toString();
}
StringBuilder res = new StringBuilder();
int carry = 0;
for (int i = maxStr.length() - 1; i >= 0; i--) {
if (a.charAt(i) == '1' && b.charAt(i) == '1'){
if (carry == 1){
res.append("1");
}else {
res.append("0");
}
carry = 1;
}else if (a.charAt(i) == '0' && b.charAt(i) == '0'){
if (carry == 1){
res.append("1");
carry = 0;
}else {
res.append("0");
}
}else {
if (carry == 1){
res.append("0");
}else {
res.append("1");
}
}
}
if (carry == 1)
res.append("1");
return res.reverse().toString();
}
}