LeetCode 力扣 67. 二进制求和

雾凇高阶
• 阅读 1819

题目描述(简单难度)

LeetCode 力扣 67. 二进制求和

两个二进制数相加,返回结果,要注意到字符串的最低位代表着数字的最高位。例如 "100" 最高位(十进制中的百位的位置)是 1,但是对应的字符串的下标是 0。

解法一

开始的时候以为会有什么特殊的方法,然后想着不管了,先按第二题两个十进制数相加的想法写吧。

public String addBinary(String a, String b) {
    StringBuilder ans = new StringBuilder();
    int i = a.length() - 1;
    int j = b.length() - 1;
    int carry = 0;
    while (i >= 0 || j >= 0) {
        int num1 = i >= 0 ? a.charAt(i) - 48 : 0;
        int num2 = j >= 0 ? b.charAt(j) - 48 : 0;
        int sum = num1 + num2 + carry;
        carry = 0;
        if (sum >= 2) {
            sum = sum % 2;
            carry = 1;
        }
        ans.insert(0, sum);
        i--;
        j--;

    }
    if (carry == 1) {
        ans.insert(0, 1);
    }
    return ans.toString();
}

时间复杂度:O(max (m,n))。m 和 n 分别是字符串 a 和 b 的长度。

空间复杂度:O(1)。

然后写完以后,在 Discuss 里逛了逛,找找其他的解法。发现基本都是这个思路,但是奇怪的是我的解法,时间上只超过了 60% 的人。然后,点开了超过 100% 的人的解法。

public String addBinary2(String a, String b) {
    char[] charsA = a.toCharArray(), charsB = b.toCharArray();
    char[] sum = new char[Math.max(a.length(), b.length()) + 1];
    int carry = 0, index = sum.length - 1;
    for (int i = charsA.length - 1, j = charsB.length - 1; i >= 0 || j >= 0; i--, j--)         {
        int aNum = i < 0 ? 0 : charsA[i] - '0';
        int bNum     = j < 0 ? 0 : charsB[j] - '0';

        int s = aNum + bNum + carry;
        sum[index--] = (char) (s % 2 + '0');
        carry = s / 2;
    }
    sum[index] = (char) ('0' + carry);
    return carry == 0 ? new String(sum, 1, sum.length - 1) : new String(sum);
}

和我的思路是一样的,区别在于它提前申请了 sum 的空间,然后直接 index 从最后向 0 依次赋值。

因为 String .charAt ( 0 ) 代表的是数字的最高位,而我们计算是从最低位开始的,也就是 lenght - 1开始的,所以在之前的算法中每次得到一个结果我们用的是 ans.insert(0, sum) ,在 0 位置插入新的数。我猜测是这里耗费了很多时间,因为插入的话,会导致数组的后移。

我们如果把 insert 换成 append ,然后再最后的结果中再倒置,就会快一些了。

public String3 addBinary(String a, String b) {
    StringBuilder ans = new StringBuilder();
    int i = a.length() - 1;
    int j = b.length() - 1;
    int carry = 0;
    while (i >= 0 || j >= 0) {
        int num1 = i >= 0 ? a.charAt(i) - 48 : 0;
        int num2 = j >= 0 ? b.charAt(j) - 48 : 0;
        int sum = num1 + num2 + carry;
        carry = 0;
        if (sum >= 2) {
            sum = sum % 2;
            carry = 1;
        }
        ans.append(sum);
        i--;
        j--;

    }
    if (carry == 1) {
        ans.append(1);
    }
    return ans.reverse().toString();
}

这里看出来多次 insert 会很耗费时间,不如最后直接 reverse。另外提前申请空间,直接根据下标赋值,省去了倒置的时间,很 cool。

更多详细通俗题解详见 leetcode.wang
点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
6个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
3年前
java 二进制(原码 反码 补码),位运算,移位运算,约瑟夫问题
一.二进制,位运算,移位运算1.二进制对于原码,反码,补码而言,需要注意以下几点:(1).Java中没有无符号数,换言之,Java中的数都是有符号的;(2).二进制的最高位是符号位,0表示正数,1表示负数;(3).正数的原码,反码,补码都一样;(4).负数的反码它的原码符号位不变,其他位取反;(5).
Wesley13 Wesley13
3年前
java中的7个位运算运算符
位运算指的是针对整数的二进制进行的位移操作。位运算提供比算术运算更高的效率,但是位运算的代码可读性较差,建议所有使用位运算的地方写上注释。Java中提供7个位运算符用于位运算。左移(<<)左移运算是将操作数二进制值逐位左移若干位,左移过程中符号位不变,高位溢出则舍弃,低位则补0。范例结果范例结果00000001<<
Wesley13 Wesley13
3年前
java按位操作符和位移操作符
一,按位操作符。1.按位与操作符(&) 如果两个数的二进制,相同位数都是1,则该位结果是1,否则是0. 例5&4    5的二进制是 0000000000000101    4的二进制是 0000000000000100    则结果是    0000000000
Stella981 Stella981
3年前
20180109Java位运算
一,Java位运算1.表示方法:  在Java语言中,二进制数使用补码表示,最高位为符号位,正数的符号位为0,负数为1。补码的表示需要满足如下要求。 (1)正数的最高位为0,其余各位代表数值本身(二进制数)。 (2)对于负数,通过对该数绝对值的补码按位取反,再对整个数加1。 2.位运算符位运算表达式由
可莉 可莉
3年前
20180109Java位运算
一,Java位运算1.表示方法:  在Java语言中,二进制数使用补码表示,最高位为符号位,正数的符号位为0,负数为1。补码的表示需要满足如下要求。 (1)正数的最高位为0,其余各位代表数值本身(二进制数)。 (2)对于负数,通过对该数绝对值的补码按位取反,再对整个数加1。 2.位运算符位运算表达式由
Stella981 Stella981
3年前
Codeforces 1208F Bits And Pieces 位运算 + 贪心 + dp
题意:给你一个序列a,问a\i\^(a\j\&a\k\)的最大值,其中i<j<k。思路:我们考虑对于每个a\i\求出它的最优解。因为是异或运算,所以我们从高位向低位枚举,如果这一位a\i\是0,我们就在a\i\的右边找两个位置让它们按位与起来这位是1。那么,我们贪心的保留可以通过按位与凑出某个二进制数的最靠右的两
Wesley13 Wesley13
3年前
JAVA位运算
位移动运算符:<<表示左移,左移一位表示原来的值乘2.例如:3<<2(3为int型)1)把3转换为二进制数字00000000000000000000000000000011,2)把该数字高位(左侧)的两个零移出,其他的数字都朝左平移2位,3)在低位(右侧)的两个空位补零。则得到的最终结果是00000000
Wesley13 Wesley13
3年前
2020 春招 华为笔试 2月26日
时间是两个小时,总共三道编程题目。第一道题目大意:  输入一个int类型的数,判断它的比特流中有多少个“010”,及第一个“101”的下标(这个下标是从低位向高位数的)。  如:输入:21      输出  20    原因:21 二进制表示为 00000000000000000000000000010101
贾蔷 贾蔷
2个月前
力扣1137题 解题思路和步骤 C++代码实现,力扣一共多少题
一、题目分析力扣1137题要求我们找到第N个泰波那契数。泰波那契数的定义是:T00,T11,T21,且在n0的条件下Tn3TnTn1Tn2。,当n4时,T4T3T2T14。这道题主要考查我们对递归或动态规划的理解和运用。在思考解题方法时,我们