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 数组形式的整数加法

  • 大整数加法问题

相关推荐
天空'之城2 小时前
C 语言工业级通用组件手写 08:精准软件消抖
c语言·嵌入式开发·工业级组件·软件消抖·按键防抖
稚南城才子,乌衣巷风流3 小时前
ST 表(Sparse Table)算法详解:原理、实现与应用
算法
hold?fish:palm3 小时前
9 找到字符串中所有字母异位词
c++·算法·leetcode
Legendary_0084 小时前
LDR6500 设计指南:Type-C 音频快充二合一配件 PD 取电与插拔时序控制方案
c语言·开发语言·音视频
Sw1zzle4 小时前
算法入门(六):贪心算法 - 基础入门(Leetcode 121/455/860/376/738)
算法·leetcode·贪心算法
青山木4 小时前
Hot 100 --- 岛屿数量
java·数据结构·算法·leetcode·深度优先·广度优先
不会就选b4 小时前
算法日常・每日刷题--<归并排序>1
数据结构·算法
危桥带雨5 小时前
排序算法(快排、归并、计数、基数排序)
数据结构·算法·排序算法
啦啦啦啦啦zzzz5 小时前
算法:回溯算法
c++·算法·leetcode