目录
题目要求
给你两个二进制字符串 a
和 b
,以二进制字符串的形式返回它们的和
示例 1:
输入:a = "11", b = "1" 输出:"100"
示例 2:
输入:a = "1010", b = "1011" 输出:"10101"
代码实现
代码演示:
void reverse(char* s)
{
int left = 0;
int right = strlen(s) - 1;
while (left < right)
{
char tmp = s[left];
s[left] = s[right];
s[right] = tmp;
left++;
right--;
}
}
char* addBinary(char* a, char* b)
{
int alen = strlen(a);
int blen = strlen(b);
// 考虑到进位和'\0',所以开辟的空间要加 2
int slen = alen > blen ? alen + 2 : blen + 2;
char* str = (char*)malloc(sizeof(char) * slen);
// 判断是否开辟成功
if (str == NULL)
{
perror("malloc");
return NULL;
}
// 反转 a 和 b 字符串,便于计算
reverse(a);
reverse(b);
int carry = 0; //判断是否进位
int sum = 0; //每一位的和
for (int i = 0; i < slen - 2; i++)
{
if (i < alen && i < blen)
sum = (a[i] - '0') + (b[i] - '0') + carry;
else if (i < alen)
sum = (a[i] - '0') + carry;
else
sum = (b[i] - '0') + carry;
if (sum < 2)
{
str[i] = sum + '0';
carry = 0;
}
else
{
if (sum == 2)
str[i] = '0';
else
str[i] = '1';
carry = 1;
}
}
if (carry == 1)
str[slen - 2] = '1';
else
slen--;
str[slen - 1] = '\0';
reverse(str);
return str;
}
代码解析:
先将 a 和 b 字符串反转,便于计算,而且计算的和要开的空间为 a 和 b 字符串中长度最大的再加 2 ,因为要考虑到进位和放置'\0'
创建变量 carry ,用于记录进位的状态,再利用 sum 把 a 和 b 对应数字和 carry 相加,再判断复制入 str 字符串中
最后再判断 carry 是否为 1 ,为 1 就再赋值,否则就 str 长度减1
代码验证:
算法的时间和空间复杂度:
for 循环执行了 N 次,每次内部常数次,额外开辟了 N + 2 的空间(去掉常数项)得出:
时间复杂度:O(N)
空间复杂度:O(N)