LeetCode 67. 二进制求和(C语言详解 | 双指针模拟加法)

一、题目描述

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

示例 1

复制代码
输入: a = "11", b = "1"
输出: "100"

示例 2

复制代码
输入: a = "1010", b = "1011"
输出: "10101"

提示

复制代码
1 <= a.length, b.length <= 10^4
a 和 b 仅由字符 '0' 或 '1' 组成
字符串如果不是 "0" ,就不含前导零

二、解题思路

这道题本质上是 二进制的大整数加法问题

思路与我们手算加法完全一样:

1️⃣ 从 字符串末尾(最低位)开始相加

2️⃣ 使用一个变量 carry 记录 进位

3️⃣ 每一位的计算规则

复制代码
sum = a位 + b位 + carry
当前位 = sum % 2
新的进位 = sum / 2

4️⃣ 因为是 从右往左计算 ,所以得到的字符串是 逆序的 ,最后需要 反转


举例说明

复制代码
a = "1010"
b = "1011"

从右往左计算:

a b carry sum 当前位
0 1 0 1 1
1 1 0 2 0 carry=1
0 0 1 1 1
1 1 0 2 0 carry=1
1 1 1

最终结果:

复制代码
10101

三、代码实现(C语言)

复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* addBinary(char* a, char* b) {

    int lenA = strlen(a);
    int lenB = strlen(b);
    
    int maxLen = lenA > lenB ? lenA : lenB;

    // 最多多一位进位
    char* res = (char*)malloc((maxLen + 2) * sizeof(char));

    int i = lenA - 1;
    int j = lenB - 1;
    int k = 0;
    int carry = 0;

    while (i >= 0 || j >= 0 || carry) {

        int sum = carry;

        if (i >= 0) sum += a[i--] - '0';
        if (j >= 0) sum += b[j--] - '0';

        res[k++] = (sum % 2) + '0';
        carry = sum / 2;
    }

    res[k] = '\0';

    // 反转字符串
    for (int l = 0, r = k - 1; l < r; l++, r--) {
        char temp = res[l];
        res[l] = res[r];
        res[r] = temp;
    }

    return res;
}

四、复杂度分析

时间复杂度

复制代码
O(n)

其中 n = max(len(a), len(b))

每个字符最多遍历一次。

空间复杂度

复制代码
O(n)

用于存储结果字符串。


五、优化思路(面试加分点)

实际上我们可以 直接从结果数组末尾填充 ,这样就 不需要反转字符串

核心思想:

复制代码
从后往前填充结果数组

这样代码会更加优雅。


六、总结

这道题的本质是 模拟二进制加法

核心步骤:

复制代码
1 从右往左遍历
2 计算 sum = a + b + carry
3 当前位 = sum % 2
4 更新进位 carry = sum / 2
5 最后反转字符串

掌握这种 字符串模拟加法思想,还可以解决很多类似问题:

  • LeetCode 415 字符串相加

  • LeetCode 989 数组形式的整数加法

  • 大整数加法问题

相关推荐
Java_2017_csdn7 小时前
ComplexKeysShardingAlgorithm 小结
java·大数据·算法
海梨花7 小时前
快手面试高频算法题
java·算法·面试
lqqjuly7 小时前
超分辨率算法深度解析(Super-Resolution Algorithms)
算法
一切皆是因缘际会7 小时前
AI智能新时代
数据结构·人工智能·ai·架构
apocelipes8 小时前
GNU GCC 多版本函数扩展
c语言·c++·linux编程
辰痕~8 小时前
指针,结构体,动态内存分配
c语言
嵌入式老牛9 小时前
液晶段码(米/日字格)识别—倾斜校正
opencv·算法·仿射变换
luj_17689 小时前
残熵算法:风险缓冲与效率优化的融合
c语言·开发语言·网络·经验分享·算法
Legendary_0089 小时前
从 DC 圆口到 USB-C PD:LED 照明设备的供电升级逻辑
c语言·开发语言
oddsand19 小时前
pgvector 三大相似度算法
人工智能·算法·机器学习