67. 二进制求和——Leetcode每日一题

Posted 期望上岸的鱼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了67. 二进制求和——Leetcode每日一题相关的知识,希望对你有一定的参考价值。

67. 二进制求和

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

示例 1:

输入:a = “11”, b = “1”
输出:“100”

示例 2:

输入:a = “1010”, b = “1011”
输出:“10101”

提示:

  • 1 < = a . l e n g t h , b . l e n g t h < = 1 0 4 1 <= a.length, b.length <= 10^4 1<=a.length,b.length<=104
  • ab 仅由字符 ‘0’ 或 ‘1’ 组成
  • 字符串如果不是 “0” ,就不含前导零

思路:

模拟位运算:

  • 从两个字符串的末尾,一步一步运算,满2进位;

优化:

  • 任意一位相加,要加三个数,分别为:
    • a 的第 i 位,
    • b 的第 i 位 ,
    • 以及前一位的进位 carry

代码:(Java、C++)

Java

public class AddBinary 

	public static void main(String[] args) 
		// TODO Auto-generated method stub
		String a = "11";
		String b = "1";
		System.out.println(addBinary(a,b));
	
	
	public static String addBinary(String a, String b) 
		
		StringBuilder  str = new StringBuilder();
		boolean carry = false;
		if(a.length() > b.length()) 
			String temp = a;
			a = b;
			b = temp;
		
		for(int i = a.length() - 1; i >= 0; i--) 
			if(a.charAt(i) == '1' && b.charAt(i + b.length() - a.length()) == '1') 
				str.append(carry == true ? '1' : '0');
				carry = true;
			else if(a.charAt(i) == '1' || b.charAt(i + b.length() - a.length()) == '1') 
				str.append(carry == true ? '0' : '1');
			else if(carry)
				str.append('1');
				carry = false;
			else 
				str.append('0');
			
		
		for(int i = b.length() - a.length() - 1; i >= 0; i--) 
			if(carry && b.charAt(i) == '1') 
				str.append('0');
			else if(carry || b.charAt(i) == 1) 
				str.append('1');
				carry = false;
			else 
				str.append(b.charAt(i));
			
		
		if(carry) 
			str.append('1');
		
		return str.reverse().toString();
    

优化:
Java

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();

C++

string addBinary(string a, string b) 
	int i = a.size() - 1, j = b.size() - 1, carry = 0;
	string str;
	while (i >= 0 || j >= 0 || carry == 1)
	
		if (i >= 0 && a[i--] == '1') 
			carry++;
		
		if (j >= 0 && b[j--] == '1') 
			carry++;
		
		str += carry % 2  + '0';
		carry /= 2;
	
	reverse(str.begin(), str.end());
	return str;

运行结果:

复杂度分析:

  • 时间复杂度 O ( n ) O(n) O(n),n位字符串ab 中长度最长的那个。
  • 空间复杂度 O ( 1 ) O(1) O(1),除去答案所占用的空间,这里使用了常数个临时变量。

题目来源:力扣。

注:仅供学习参考, 如有不足,欢迎指正!

《LeetCode之每日一题》:150.二进制求和

二进制求和


题目链接: 二进制求和

有关题目

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

输入为 非空 字符串且只包含数字 10
示例 1:

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

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

每个字符串仅由字符 '0''1' 组成。
1 <= a.length, b.length <= 10^4
字符串如果不是 "0" ,就都不含前导零。

题解

法一:模拟

模拟,逢二进一
为保证位数对齐,我们将a,b反转, 以a,b中长度最长的为界限,从前往后遍历
最后注意,验证最后进位的

代码一:

class Solution {
public:
    string addBinary(string a, string b) {        
        string ans = "";
        reverse(begin(a), end(a));
        reverse(begin(b), end(b));

        int n = max(a.size(), b.size()), add = 0;
        for (int i = 0; i < n; ++i){
            int x = i < a.size() ? a[i] - '0' : 0;
            int y = i < b.size() ? b[i] - '0' : 0;
            int res = x + y + add;
            ans.push_back(res % 2 + '0');
            add = res / 2;
        }
        if (add != 0){
            ans.push_back(add % 2 + '0');
        }
        reverse(begin(ans), end(ans));
        return ans;
    }
};

代码二:

思路:
这次我们从后往前遍历,逢二进一,最后别忘记反转一下
class Solution {
public:
    string addBinary(string a, string b) {
        int m = a.size() - 1, n = b.size() - 1, add = 0;
        string ans = "";
        while(m >= 0 || n >= 0 || add){
            int x = m >= 0 ? a[m] - '0' : 0;
            int y = n >= 0 ? b[n] - '0' : 0;
            int res = x + y + add;
            ans.push_back(res % 2 + '0');
            add = res / 2;
            --m, --n;
        }
        reverse(ans.begin(), ans.end());
        return ans;
    }
};

以上是关于67. 二进制求和——Leetcode每日一题的主要内容,如果未能解决你的问题,请参考以下文章

leetcode 每日一题 67. 二进制求和

《LeetCode之每日一题》:150.二进制求和

《LeetCode之每日一题》:67.二进制手表

LeetCode八月每日一题题解(个人记录打卡)

LeetCode八月每日一题题解(个人记录打卡)

LeetCode八月每日一题题解(个人记录打卡)