LeetCode算法题:二进制求和

一道简单的算法题,题目描述如下:

给定两个二进制字符串,返回他们的和(用二进制表示)。

输入为非空字符串且只包含数字 1 和 0。

示例 1:

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

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

这道题用暴力法思路很简单,但是写起来很麻烦。二进制大家都知道如何计算,也知道如何进位,我们认为的来算感觉很简单,但是设计算法让计算机按照人类的思路(人类大脑计算二进制加法的方法类似于求解这道题的暴力法)来算的话,算法设计的很麻烦。废话不多说了,直接贴代码:

暴力法:

class Solution {
public:
    string addBinary(string a, string b) {
        int len1=a.size(),len2=b.size();
        int carry=0;
        string result;
        //如果a和b之中任何一个为空,那么返回另一个
        if(len1==0){
            return b;
        }
        else if(len2==0){
            return a;
        }
        //暴力法的循环,循环到某一个字符串的长度减为0为止
        while(len1>0&&len2>0){
            //相同位置上都是0的情况
            if(a[len1-1]=='0'&&b[len2-1]=='0'){
                //如果进位也是0,那么result左边添加一个0
                if(carry==0){
                    result = '0'+result;
                }
                //如果进位不是0,那么结果加进位,然后进位置零
                else if(carry==1){
                    result = '1'+result;
                    carry = 0;
                }
            }
            //相同位置上都是1的情况
            else if(a[len1-1]=='1'&&b[len2-1]=='1'){
                if(carry==0){
                    result = '0'+result;
                    carry = 1;
                }
                else if(carry==1){
                    result = '1'+result;
                }
            }
            //最后一种情况就是a和b相同位置上一个是1另一个是0
            else{
                if(carry==0){    
                    result = '1'+result;
                }
                else if(carry==1){
                    result = '0' + result;
                    carry = 1;
                }
            }
            len1--;
            len2--;
        }    
        
        /*接下来的两个判断语句,就是一个字符串比另一个字符串
          长所产生的情况,按照人的想法是很好理解的,只要注意
          进位问题就行了,这里就不详细解释了*/
        if(len1>0){
            if(carry==0){
                while(len1>0){
                    result = a[len1-1] + result;
                    len1--;
                }
            }
            else if(carry==1){
                while(len1>0){
                    if(carry==0){
                        result = a[len1-1] + result;
                    }
                    else if(carry==1){
                        if(a[len1-1]=='0'){
                            carry = 0;
                            result = '1'+result;
                        }
                        else{
                            carry = 1;
                            result = '0'+result;
                        }
                    }
                    len1--;
                }
            }
        }
        if(len2>0){
            if(carry==0){
                 while(len2>0){
                    result = b[len2-1] + result;
                    len2--;
                }
            }
            else if(carry==1){
                while(len2>0){
                    if(carry==0){
                        result = b[len2-1] + result;
                    }
                    else if(carry==1){
                        if(b[len2-1]=='0'){
                            carry = 0;
                            result = '1'+result;
                        }
                        else{
                            carry = 1;
                            result = '0'+result;
                        }
                    }
                    len2--;
                }
            }
        }
        /*最后这个if语句比较重要,判断两个字符串都加
          完后进位是否为0,比较容易被人忽略*/
        if(len1==0&&len2==0&&carry==1){
            result = '1'+result;
        }
        return result;
    }
};

上面的代码就是暴力法,大家也看的出来,这个算法无论是时间复杂性还是空间复杂性都很高,效率极低,但是有利于理解。

下面贴一个外国大佬(Sun Josan)的代码,只用了十行。

class Solution {
public:
    string addBinary(string a, string b) {
        string s;
		s.reserve(a.size() + b.size());
		int c = 0, i = a.size() - 1, j = b.size() - 1;
		while(i >= 0 || j >= 0 || c == 1)
		{
			c += i >= 0 ? a[i--] - '0' : 0;
			c += j >= 0 ? b[j--] - '0' : 0;
			s.push_back((c & 1) + '0');
			c >>= 1;
		}
		reverse(s.begin(), s.end());
		return s;
    }
};

字符串reserve函数的作用:reverse()会将区间[beg,end)内的元素全部逆序;

下面贴Python3的代码,Python3的代码用了递归,代码行数较少:

"""
递归,退出条件为a, b任意一个为空字符串。

加两数的末位决定是否进位。

末位加完,递归加前面的部分即可。
"""

class Solution:
    def addBinary(self, a: str, b: str) -> str:
        if a=='':
            return b
        if b=='':
            return a
        # 如果任意一个为0,则不需要进位,直接递归加前面的部分即可
        if a[-1]=='0' or b[-1]=='0':
            last = '0' if a[-1]==b[-1] else '1'
            return self.addBinary(a[:-1],b[:-1]) + last
        else:
            # 末位均为1,需要进位
            # 给a前面的部分添一位后再与b前面的部分递归加和
            last = '0'
            a = self.addBinary(a[:-1],'1')
            return self.addBinary(a,b[:-1]) + last

如果有写的不合理的地方还望各位朋友批评指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值