【每日一题】67. 二进制求和

67. 二进制求和 - 力扣(LeetCode)

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

示例 1:

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

示例 2:

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

提示:

  • 1 <= a.length, b.length <= 104
  • a 和 b 仅由字符 '0' 或 '1' 组成
  • 字符串如果不是 "0" ,就不含前导零
class Solution {
    public String addBinary(String a, String b) {
        String pre = "1";
        int lena = a.length();
        int lenb = b.length();
        int len = lena>lenb?lena:lenb;
        StringBuffer str = new StringBuffer(len);
        lena-=1;
        lenb-=1;
        int flag = 0;
        while(lena >= 0&&lenb >= 0) {
            if(a.charAt(lena) == b.charAt(lenb)) {
                if(a.charAt(lena) == '0') {
                    if(flag == 1) {
                        str.insert(0,1);
                        flag = 0;
                    } else {
                        str.insert(0,0);
                    }
                } else {
                    if(flag == 1) {
                        str.insert(0,1);
                        flag = 1;
                    } else {
                        str.insert(0,0);
                        flag = 1;
                    }
                }
            } else {
                if(flag == 1) {
                    str.insert(0,0);
                    flag = 1;
                } else {
                    str.insert(0,1);
                }
            }
            lena--;
            lenb--;
        }

        while(lena >= 0) {
            if(a.charAt(lena) == '1') {
                if(flag == 1) {
                    str.insert(0,0);
                    flag = 1;
                } else {
                    str.insert(0,1);
                }
            } else {
                if(flag == 1) {
                    str.insert(0,1);
                    flag = 0;
                } else {
                    str.insert(0,0);
                }
            }
            lena--;
        }

        //System.out.print(flag);

        while(lenb >= 0) {
            if(b.charAt(lenb) == '1') {
                if(flag == 1) {
                    str.insert(0,0);
                    flag = 1;
                } else {
                    str.insert(0,1);
                }
            } else {
                if(flag == 1) {
                    str.insert(0,1);
                    flag = 0;
                } else {
                    str.insert(0,0);
                }
            }
            lenb--;
        }
        //System.out.print(flag);
        if(flag == 1) return pre+str.toString();
        return str.toString();
    }

}

         今天是一道简单题。

        这道题其实看完之后估计大家都会想到的解法差不多。暴力的就直接转int,相加之后判断,再转回string。博主这里没有这么做,博主类型互转学得不是很好,转成int数组之后就转回来就很麻烦。(博主用的方法)。所以干脆就直接用最熟悉的StringBuffer。

        由于两个要进行相加,而n位数相加,最多只可能产生n+1位的数。而且这里只需要再思考一个问题:进位了之后会是什么?如果有进位,那么一定只会是1,而且1在最前面。所以,可以用pre表示1,如果最后需要就字符串相加返回。其次,无论什么运算肯定是要对位的,两个数有可能位数不一样,那创建StringBuffer时肯定要以位数多的为主,StringBuffer可以使用insert()一直往(0,x)插入,那么就很方便可以进行低位到高位的运算。从a,b的最低位相加,用flag判断是否有进位,分别对(1,1);(1,0);(0,1);(0,0)的情况进行判断即可,最后出来之后,有可能有高位是不需要再和另一个串相加的,所以要把没有结束的再来一次。

        最后判断一下最高位有无进位,如果有,就需要加上pre前缀返回。没有就不需要。

题解:

class Solution {
    public String addBinary(String a, String b) {
        StringBuilder ans = new StringBuilder();
        int ca = 0;
        for(int i = a.length() - 1, j = b.length() - 1;i >= 0 || j >= 0; i--, j--) {
            int sum = ca;
            sum += i >= 0 ? a.charAt(i) - '0' : 0;
            sum += j >= 0 ? b.charAt(j) - '0' : 0;
            ans.append(sum % 2);
            ca = sum / 2;
        }
        ans.append(ca == 1 ? ca : "");
        return ans.reverse().toString();
    }
}

        题解大佬的思路就更简洁了。从尾到头相加,sum来表示两个字符串相应位相加完的总和,ca则表示前一位运算有无进位。相加只有0,1,2,3的结果,超过2才需要进位,所以可以用/2来判断,%2则可以找出留下的数。由于+=的运算顺序是最后,所以会先运算?:运算。位数少的就会使用0来补。最后,由于使用的append(),所以最后结果是相反的,需要反转一下。

        题解可以大家好好看看,很精妙的写法。

        如果有其他写法,也可以发在评论区。

你可能感兴趣的:(每日一题,算法,java,力扣)