[leetCode]67.二进制求和
解法1
先将a、b转化为10进制整数相加在转化为二进制字符串.
但是Java 中:
- 如果字符串超过 33 位,不能转化为
Integer
- 如果字符串超过 65 位,不能转化为
Long
- 如果字符串超过 500000001位,不能转化为
BigInteger
class Solution {
public String addBinary(String a, String b) {
return Integer.toBinaryString(
Integer.parseInt(a, 2) + Integer.parseInt(b, 2));
}
}
解法二
借鉴列竖式
将a、b末端对其,逐位相加逢2进1,用carry
保存上一位的进位,则每一位的答案为
(
c
a
r
r
y
+
a
i
+
b
i
)
%
2
(carry + a_i + b_i)\% 2
(carry+ai+bi)%2,每一位的进位为
(
c
a
r
r
y
+
a
i
+
b
i
)
%
2
(carry + a_i + b_i)\% 2
(carry+ai+bi)%2,如果最后一位进位为1则再字符串头部补1。下面的代码先对不同长度的字符串进行了补齐,再进行逐位相加。
class Solution {
public String addBinary(String a, String b) {
int len = Math.max(a.length(), b.length());
while(a.length() < b.length())a="0"+a;//补0
while(b.length() < a.length())b="0"+b;
int carry = 0;
String ans = "";
for(int i = len -1; i >=0; i--) {
int k = Integer.valueOf(a.charAt(i)) - 48,l = Integer.valueOf(b.charAt(i))-48;
ans = ((k+l+carry)%2) + ans;
carry = (k + l + carry)/2;
}
if(carry == 1)ans = "1"+ans;
return ans;
}
}
下面的代码没有进行补齐也能进行相加。
class Solution {
public String addBinary(String a, String b) {
StringBuffer ans = new StringBuffer();
int len = Math.max(a.length(), b.length()), carry = 0;
for(int i = 0; i < len; i++){
carry += i < a.length() ? a.charAt(a.length() -1 -i) - '0': 0;
carry += i < b.length() ? b.charAt(b.length() -1 -i) - '0': 0;
ans.append((char)(carry%2 + '0'));
carry /=2;
}
if(carry == 1){
ans.append('1');
}
return ans.reverse().toString();
}
}
解法三
使用位运算代替加法,可以有以下算法:
把a、b转化为十进制整形数字x、y,使用x保存结果,y保存进位
- 计算当前x与y的无进位相加结果:
answer = x ^ y
‘ - 计算当前x与y的进位:
carry = (x & y) << 1
- 完成循环更新:
x = answer
,y = carry
返回x的二进制形式
该算法模拟了进位左移,直到无进位时加法结束
class Solution {
public String addBinary(String a, String b) {
int x = Integer.parseInt(a,2), y = Integer.parseInt(b,2);//把字符串转化为十进制整数
int answer, carry;
while(y!=0){
answer = x ^ y;//无进位的相加结果
carry = (x & y) << 1;//计算进位
x = answer;
y = carry;
}
return Integer.toBinaryString(x);
}
}