当前位置: 首页 > news >正文

LeetCode算法日记 - Day 34: 二进制求和、字符串相乘

目录

1. 二进制求和

1.1 题目解析

1.2 解法

1.3 代码实现

2. 字符串相乘

2.1 题目解析

2.2 解法

2.3 代码实现


1. 二进制求和

67. 二进制求和 - 力扣(LeetCode)

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

示例 1:

输入:a = "11", b = "1"
输出:"100"

示例 2:

输入:a = "1010", b = "1011"
输出:"10101"

提示:

  • 1 <= a.length, b.length <= 104
  • a 和 b 仅由字符 '0' 或 '1' 组成
  • 字符串如果不是 "0" ,就不含前导零

1.1 题目解析

题目本质:
把两个仅含 0/1 的长字符串当成二进制大整数,相加并以二进制字符串返回。本质就是“逐位相加 + 维护进位”。

常规解法:
把二进制转成整型/长整型相加,再转回二进制。

问题分析:
长度可达 10^4,超出整型范围;而且频繁进制转换不必要、易溢出。应当直接在字符串层面做“竖式加法”。预计最佳复杂度:一次线性扫描 O(n)

思路转折:
要想高效且安全 → 不做数值转换 → 双指针从右到左逐位相加,sum = carry + bitA + bitB,当前位写 sum % 2,新的进位 sum / 2
这样无需补零,只要在循环里判断指针是否越界即可;最后把构建的结果反转即可得到正确顺序。

1.2 解法

算法思想:设 i = a.length()-1、j = b.length()-1、carry = 0。循环条件:i>=0 || j>=0 || carry!=0。 每轮:

  • sum = carry + (i>=0 ? a[i]-'0' : 0) + (j>=0 ? b[j]-'0' : 0)

  • 结果位:sum % 2

  • 新进位:sum / 2

i)置双指针到两串末尾,carry=0,准备 StringBuilder(可预分配容量 maxLen+1)。

ii)循环:只要任一串未遍历完或还有进位,就继续:

  • 读各自当前位(越界当 0);

  • 相加得 sum;

  • append(sum % 2) 到 sb(此时是低位在前);

  • carry = sum / 2;指针左移。

iii)循环结束后 sb.reverse() 得到最终结果。

易错点:

  • while 条件必须是 carry != 0,不能写成 carry >= 0,否则可能死循环。

  • charAt(i) 是字符,要先减 '0' 转为数值位。

  • 右到左加;别从左往右。

  • 注意不等长字符串:用 if (i>=0)/if (j>=0) 判断是否还能取位。

  • StringBuilder.append(int) 对 0/1是安全的;也可写 append((char)('0' + (sum & 1)))。

  • 别在循环里频繁字符串拼接 +,会产生大量中间对象,影响性能。

1.3 代码实现

class Solution {public String addBinary(String a, String b) {int i = a.length() - 1, j = b.length() - 1;int carry = 0;// 预估容量:最大长度 + 1(可能多出一个进位)StringBuilder sb = new StringBuilder(Math.max(a.length(), b.length()) + 1);while (i >= 0 || j >= 0 || carry != 0) {int sum = carry;if (i >= 0) sum += a.charAt(i--) - '0';if (j >= 0) sum += b.charAt(j--) - '0';sb.append(sum % 2);   // 当前位carry = sum / 2;      // 新进位}return sb.reverse().toString();}
}

复杂度分析:

  • 时间:O(n),其中 n = max(|a|, |b|),每位最多访问一次。

  • 空间:O(n),StringBuilder 存放结果(最坏多一位进位)。

2. 字符串相乘

43. 字符串相乘 - 力扣(LeetCode)

给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。

示例 1:

输入: num1 = "2", num2 = "3"
输出: "6"

示例 2:

输入: num1 = "123", num2 = "456"
输出: "56088"

提示:

  • 1 <= num1.length, num2.length <= 200
  • num1 和 num2 只能由数字组成。
  • num1 和 num2 都不包含任何前导零,除了数字0本身。

2.1 题目解析

题目本质:
把两个十进制数字串当作“大整数”做乘法,返回其十进制字符串。可抽象为“竖式乘法在字符串层面的模拟”。

常规解法:
直接把 num1/num2 转为内置整数或 BigInteger 再相乘,最后转回字符串。

问题分析:
数据长度可达 200,超出 64 位整数范围;题目也禁止用大整数库或直接转整型。必须在字符/数组层面完成乘法。理想复杂度为 O(mn)(m、n 为两字符串长度),空间 O(m+n)

思路转折:
要想安全且高效 → 放弃内置数值运算 → 用“竖式乘法”:

  • 两两相乘,按位权落在正确的“结果槽位”上;

  • 把所有乘积先累加到对应槽位(相当于“卷积”);

  • 最后统一处理进位,再生成字符串。
    这样实现清晰、易于调试,也能稳定做到 O(mn)。

2.2 解法

算法思想:算法思想:
令 a = reverse(num1)、b = reverse(num2)(把最低位放前面),准备长度为 m+n-1 的整型数组 tmp 用于“无进位卷积”:

mp[i+j]+=(a[i]−′0′)⋅(b[j]−′0′)

然后从低到高扫描 tmp:

sum←carry+tmp[cur],输出(sum%10),carry←⌊sum/10⌋

若扫描完仍有 carry,继续“吐出”高位。最后反转得到正常顺序,并去掉可能出现的前导零。

i)特判:若任一输入为 "0",直接返回 "0"

ii)反转两个字符串并转为 char[]。

iii)申请int[] tmp(长度 m+n-1),双重循环累加 tmp[i+j] += (a[i]-'0')*(b[j]-'0')。

iiii)统一进位:用一个移动的 carry 从 tmp[0] 扫到 tmp[len-1],每步输出当前个位、更新进位;若 carry 仍非 0,继续输出直到为 0。

iiiii)删除将来会变成前导零的尾部 0(因为此时字符串是“低位在前”),再反转得到答案。

易错点:

  • 卷积阶段必须是 +=,不能写成 =(会覆盖之前累加)。

  • 记得把字符转数字:ch - '0'。

  • 结果桶长度为 m+n-1(卷积长度);统一进位阶段会把最高位的进位继续“吐出来”(所以最终位数≤m+n)。

  • 统一进位的循环条件建议写成 while (cur < tmp.length || carry != 0);sum 初始化为 carry,再按需加 tmp[cur]。

  • 去“前导零”的时机:在反转之前删尾部 0(至少保留 1 位,避免把 0 本身清空)。

2.3 代码实现

class Solution {public String multiply(String num1, String num2) {// 1) 边界:任一为 "0"if (num1.equals("0") || num2.equals("0")) return "0";int m = num1.length(), n = num2.length();char[] a = new StringBuilder(num1).reverse().toString().toCharArray();char[] b = new StringBuilder(num2).reverse().toString().toCharArray();// 2) 无进位卷积:长度 m + n - 1int[] tmp = new int[m + n - 1];for (int i = 0; i < m; i++) {int di = a[i] - '0';for (int j = 0; j < n; j++) {int dj = b[j] - '0';tmp[i + j] += di * dj; // 累加!!不是覆盖}}// 3) 统一进位:从低到高,把每格拆成 个位(输出) + 进位(带走)StringBuilder sb = new StringBuilder(m + n);int cur = 0, carry = 0;while (cur < tmp.length || carry != 0) {if (cur < tmp.length) carry += tmp[cur++];sb.append((char) ('0' + (carry % 10)));carry /= 10;}// 4) 去掉将来会成为“前导零”的尾部 0(至少保留1位)while (sb.length() > 1 && sb.charAt(sb.length() - 1) == '0') {sb.deleteCharAt(sb.length() - 1);}// 5) 反转得到正常顺序return sb.reverse().toString();}
}

复杂度分析:

  • 时间:O(mn),双重循环累积卷积项,统一进位线性扫描一次。

  • 空间:O(m+n),tmp 与输出字符串(最坏 m+n 位)。


文章转载自:

http://vQom9gzv.nwjzc.cn
http://VpyJCqPI.nwjzc.cn
http://bvWwGQOE.nwjzc.cn
http://kZTPlbhF.nwjzc.cn
http://I8PGx8dE.nwjzc.cn
http://lhsEsIc9.nwjzc.cn
http://iILpARJm.nwjzc.cn
http://AwYfxMX9.nwjzc.cn
http://scoTtzwT.nwjzc.cn
http://npk4zgRV.nwjzc.cn
http://1lIapUVL.nwjzc.cn
http://J93hRcXM.nwjzc.cn
http://rDmscpNS.nwjzc.cn
http://hMkas1wY.nwjzc.cn
http://KW8AQ6ce.nwjzc.cn
http://Cp9ebeC0.nwjzc.cn
http://58kCmPll.nwjzc.cn
http://IpUHyAfp.nwjzc.cn
http://Fr6iBu7w.nwjzc.cn
http://W1YtgXq5.nwjzc.cn
http://AuB68TlY.nwjzc.cn
http://6YqkhVXs.nwjzc.cn
http://O5UF2PXD.nwjzc.cn
http://EUgH2iRp.nwjzc.cn
http://QiLUyvgr.nwjzc.cn
http://WuBq7Jmq.nwjzc.cn
http://mxtuEUfT.nwjzc.cn
http://4KledqPG.nwjzc.cn
http://xj4goopB.nwjzc.cn
http://UupJyVR6.nwjzc.cn
http://www.dtcms.com/a/369910.html

相关文章:

  • 【PyTorch实战:Tensor】4、NumPy与PyTorch Tensor指南:深度学习中的数据操作与转换
  • W25Q128
  • 【LeetCode热题100道笔记】二叉树展开为链表
  • 【LeetCode热题100道笔记】对称二叉树
  • MySQL与ES索引区别
  • 捷多邦揭秘超厚铜板:从制造工艺到设计关键环节​
  • Nestjs框架: 基于权限的精细化权限控制方案与 CASL 在 Node.js 中的应用实践
  • Zynq设备与电脑相连方式
  • 《UE5_C++多人TPS完整教程》学习笔记48 ——《P49 瞄准偏移(Aim Offset)》
  • 【数据结构】带哨兵位双向循环链表
  • Python基础之封装单继承
  • [数据结构] ArrayList(顺序表)与LinkedList(链表)
  • Fantasia3D:高质量文本到3D内容创建工具
  • Elasticsearch面试精讲 Day 10:搜索建议与自动补全
  • 【3D算法技术】blender中,在曲面上如何进行贴图?
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘mkdocs’问题
  • 【牛客刷题-剑指Offer】BM18 二维数组中的查找:一题四解,从暴力到最优
  • 推荐的Java服务环境:JDK17+ZGC(JDK 21的ZGC支持分代回收,性能更高)
  • [光学原理与应用-431]:非线性光学 - 能生成或改变激光波长的物质或元件有哪些?
  • 心路历程- Linux用户组的整理
  • 前端登录鉴权详解
  • CodeSandbox Desktop:零配置项目启动工具,实现项目环境隔离与Github无缝同步
  • Lua > Mac Mini M4安装openresty
  • SpringBootWeb 篇-深入了解 ThreadLocal 存在内存泄漏问题
  • Django 项目6:表单与认证系统
  • 【架构艺术】通过标准化事件解决变更检测能力的调度问题
  • Eureka与Nacos的区别-服务注册+配置管理
  • Python毕业设计推荐:基于Django的饮食计划推荐与交流分享平台 饮食健康系统 健康食谱计划系统
  • 基于 Gemini 的 CI/CD 自动化测评 API 集成实战教程
  • 基于定制开发开源AI智能名片S2B2C商城小程序的DMP平台离线文件上传功能优化研究