问题描述
小U和小R希望设计一个算法,将两个可能非常长的二进制字符串进行相加,并将结果以十进制形式返回。由于二进制字符串可能很长,常规的整数加法无法处理,因此需要设计一个能支持大数操作的高效算法。
解题思路
1. 问题分解
- 二进制加法:
- 遵循基本的二进制加法规则:
0 + 0 = 01 + 0 = 11 + 1 = 10(结果为0,进位1)
- 每一位的计算需要考虑进位。
- 遵循基本的二进制加法规则:
- 输出十进制:
- 将计算得到的二进制和,转换为十进制输出。
2. 算法设计
- 长度对齐:
- 如果两个二进制字符串长度不同,较短的需要在前面补零,或者从尾部开始对齐进行逐位相加。
- 逐位相加:
- 从两个字符串的末尾开始,逐位相加。
- 根据二进制规则计算每一位的结果,并跟踪是否有进位。
- 处理剩余的较长部分:
- 如果较长字符串有未处理的部分,需要继续处理并考虑进位。
- 进位处理:
- 如果所有位处理完后仍有进位,则需要在结果的最高位补
1。
- 如果所有位处理完后仍有进位,则需要在结果的最高位补
- 结果转换:
- 得到的二进制结果需要转换为十进制格式输出。
代码实现
public class Main {
public static String solution(String binary1, String binary2)
{
StringBuilder str = new StringBuilder(); // 存储结果的二进制字符串
boolean carry = false; // 标记是否有进位
// 确保 binary1 是较短的字符串,binary2 是较长的字符串
if (binary1.length() > binary2.length())
{
String temp = binary1;
binary1 = binary2;
binary2 = temp;
}
// 从末尾对齐逐位相加
for (int i = binary1.length() - 1; i >= 0; i--)
{
int idx2 = i + binary2.length() - binary1.length(); // binary2 对应的索引
char b1 = binary1.charAt(i), b2 = binary2.charAt(idx2);
if (b1 == '1' && b2 == '1')
{ // 1 + 1 的情况
str.append(carry ? '1' : '0'); // 如果有进位,加上 1
carry = true;
}
else if (b1 == '1' || b2 == '1') // 1 + 0 或 0 + 1 的情况
str.append(carry ? '0' : '1'); // 如果有进位,结果为 0
else // 0 + 0 的情况
{
str.append(carry ? '1' : '0');
carry = false;
}
}
// 处理 binary2 剩余部分
for (int i = binary2.length() - binary1.length() - 1; i >= 0; i--)
{
char b2 = binary2.charAt(i);
if (carry && b2 == '1')
str.append('0');
else if (carry || b2 == '1')
{
str.append('1');
carry = false;
}
else
str.append(b2);
}
if (carry)
str.append('1');
String binarySum = str.reverse().toString();
return Integer.toString(Integer.parseInt(binarySum, 2));
}
public static void main(String[] args) {
System.out.println(solution("101", "110").equals("11"));
System.out.println(solution("111111", "10100").equals("83"));
System.out.println(solution("111010101001001011", "100010101001").equals("242420"));
System.out.println(solution("111010101001011", "10010101001").equals("31220"));
}
}
复杂度分析
- 时间复杂度:
- 对两个二进制字符串逐位相加的复杂度为
O(n),其中n是较长字符串的长度。 - 二进制结果转换为十进制的复杂度为
O(n)。 - 总时间复杂度为
O(n)。
- 对两个二进制字符串逐位相加的复杂度为
- 空间复杂度:
- 结果存储使用了一个长度为
n+1的字符串构造器,空间复杂度为O(n)。
- 结果存储使用了一个长度为
关键点总结
- 二进制加法规则:
- 需要正确处理二进制加法规则,包括进位和边界条件。
- 对齐操作:
- 长度较短的字符串需要与较长字符串尾部对齐,避免错位操作。
- 边界处理:
- 处理进位时要注意最后一位是否需要补
1。
- 处理进位时要注意最后一位是否需要补
- 大数支持:
- 使用字符串模拟大数加法,无需依赖语言原生的整数运算。