LeetCode67(二进制求和[位运算,大数运算])
二进制求和
题目要求:
给你两个二进制字符串 a 和 b ,以二进制字符串的形式返回它们的和。
这道题其实有几种解法.我们先来介绍简单的方法.
我们可以将两个字符串的二进制转成十进制,获取对应值相加之后,我们可以不断对2取余,获取尾数拼接即可.也就是像我们平常求一个十进制的二进制数,可以递归调用,同样也可以迭代.官方题解当中给我们介绍了一种Java自带的API解法,如下所示
class Solution {public String addBinary(String a, String b) {return Integer.toBinaryString(Integer.parseInt(a, 2) + Integer.parseInt(b, 2));}
}
但是这种解法具有局限性,官方提到:
如果 a 的位数是 n,b 的位数为 m,这个算法的渐进时间复杂度为 O(n+m)。但是这里非常简单的实现基于 Python 和 Java 本身的高精度功能,在其他的语言中可能并不适用,并且在 Java 中:
- 如果字符串超过 33 位,不能转化为 Integer
- 如果字符串超过 65 位,不能转化为 Long
- 如果字符串超过 500000001 位,不能转化为 BigInteger
所以我们需要一个更加健全的解法
对于这两个字符串,我们可以对最末端,不断相加,若有进位,保留进位相加.一步步拼接字符串.由于是二进制的运算,我们很容易联系到位运算
.
对于位运算来讲,十进制的相加我们可以模拟成(a b 相加)
无进位时
: sum = a ^ b
有进位时
: sum = a ^ b + (a & b) << 1
例如: a = 3 b = 1 时
我们将其转换为二进制
a: 11
b: 01
我们先进行异或运算可以求的没有进位的位相加的结果,这里我们可以得到
temp = 10;
其次我们来求得需要进位的位置,需要进位其实就是上下两端都等于1时,所以我们可以用&运算来实现我们的需求
求得 carry = 01
;左移一位得到 carry = 10
;
重复上述过程,直至(a & b) == 0即没有进位为止
temp ^ carry = 00;
temp & carry = 10;
左移相加得到 100;满足相加的结果.
而这里我们只需要对当前与进位数相加后,计算此时进位的值,循环往复即可,所以公式得到
sum = x ^ y ^ carry;
carry = (x & y) [这里是有点问题的,我们后面再讨论]
所以我们初步的解题步骤为
我们需要比较两个字符串长度最小值选取为第一次循环的终止条件,然后从字符串的最后面开始遍历,不断对最后一位进行异或运算.代码为
int size = Math.min(aLength,bLength);int carry = 0;StringBuilder sb = new StringBuilder();for(int i = 0;i < size;i++){int x = a.charAt(--aLength)-'0';int y = b.charAt(--bLength)-'0';int sum = (x ^ y ^ carry);carry = ( x & y) ; sb.append(sum);}
这段代码其实是有一点问题的,我们思考下面这种情形.
当x = 1 , y = 0 ,carry = 1时
我们的 carry 计算公式为 = x & y
这样将会错过进位的运算.
那会有人提出三个数做异或运算呗,像那个sum一样
注意:
我们sum求值概念为三数求值相加后余下来的值
,所以我们对三个数做异或运算就可以满足此特性.
但是此时进位处和其不太一样
我们需要只要出现两个1,我们的进位就应该是1.
那我们先来思考x与y的取值有几种情形
x = 1 y = 0
x = 0 y = 1
x = 0 y = 0
x = 1 y = 1
我们讨论的情况当carry = 1时.属于x,y中最多只有一个数出现为1时,我们需要进位 置1.也就是我们进行xy的异或运算后再进行对carry的&运算.
而对于carry = 0而且x与y都等于1时,我们不需要carry进行对应的运算.
所以我们列出改进后的代码
for(int i = 0;i < size;i++){int x = a.charAt(--aLength)-'0';int y = b.charAt(--bLength)-'0';int sum = (x ^ y ^ carry);//carry == 1 x==1 y==0 如果采用x&y 这里会错过进位if(carry == 1 && x!=1 && y!=1){carry = (x^y) & carry ;}else if(carry == 0) carry = ( x & y) ;sb.append(sum);}
此时我们已经完成了较短的字符串的二进制运算
而对于剩下的那个我们仍需要进行字符串的拼接,但我们需要注意的是
可能在第一次循环过后最后相加的那个结点处,我们产生了进位,所以我们依旧需要对进位进行处理.
while (aLength > 0){int x = a.charAt(--aLength)-'0';int sum = (x ^ carry);carry = ((x&carry));sb.append(sum);}while (bLength > 0){int y = b.charAt(--bLength)-'0';int sum = (y ^ carry);carry = ((y&carry));sb.append(sum);}
看样子好像已经挺完善啦,其实我们还是漏了一点.也就是当两个字符串都遍历完后.如果此时最高位产生了进位,我们是需要扩展原来的长度,即再加一位来存放最高处的进位.
所以完整代码为
class Solution {public String addBinary(String a, String b) {int aLength = a.length();int bLength = b.length();if(aLength < 1) return b;if(bLength < 1) return a;int carry = 0;int size = Math.min(aLength,bLength);StringBuilder sb = new StringBuilder();for(int i = 0;i < size;i++){int x = a.charAt(--aLength)-'0';int y = b.charAt(--bLength)-'0';int sum = (x ^ y ^ carry);//carry == 1 x==1 y==0 如果采用x&y 这里会错过进位if(carry == 1 && x!=1 && y!=1){carry = (x^y) & carry ;}else if(carry == 0) carry = ( x & y) ;sb.append(sum);}while (aLength > 0){int x = a.charAt(--aLength)-'0';int sum = (x ^ carry);carry = ((x&carry));sb.append(sum);}while (bLength > 0){int y = b.charAt(--bLength)-'0';int sum = (y ^ carry);carry = ((y&carry));sb.append(sum);}if(carry > 0) sb.append(carry);return sb.reverse().toString();}
}
结果为:
相关文章:

LeetCode67(二进制求和[位运算,大数运算])
二进制求和 题目要求: 给你两个二进制字符串 a 和 b ,以二进制字符串的形式返回它们的和。 这道题其实有几种解法.我们先来介绍简单的方法. 我们可以将两个字符串的二进制转成十进制,获取对应值相加之后,我们可以不断对2取余,获取尾数拼接即可.也就是像我们平常求一…...

grep对文件内容搜索(附重要拓展-正则表达式)
文件搜索是搜索查找符合条件的某文件的目录,若要编辑文件或对文件的某配置进行修改,就需要对文件内容进行搜索。 grep 命令是 Linux 及类 Unix 操作系统中的一个强大的文本搜索工具,用于搜索一个或多个文件中匹配给定模式的行。grep 代表“Gl…...

前端JS特效第26波:jQuery日期时间选择器插件
jQuery日期时间选择器插件,先来看看效果: 部分核心的代码如下: <!DOCTYPE html> <html> <head lang"zh-CN"> <meta charset"UTF-8"> <title>jQuery日期时间选择器插件 - PHP中文网</t…...

Anaconda+Pycharm 项目运行保姆级教程(附带视频)
最近很多小白在问如何用anacondapycharm运行一个深度学习项目,进行代码复现呢?于是写下这篇文章希望能浅浅起到一个指导作用。 附视频讲解地址:AnacondaPycharm项目运行实例_哔哩哔哩_bilibili 一、项目运行前的准备(软件安装&…...
java面试-java基础(上)
文章目录 一、什么是Java?特点?二、什么是JVM、JDK、JRE?三、java跨平台实现原理四、java数据类型有哪些?五、char能不能存一个中文汉字?六、存在数字i加1小于i或者i减1小于i?七、什么是自动类型转换与强制类型转换?八、什么是装/拆箱&am…...

STM32快速搭建项目框架
注:编写本博客的原因,学习期间基于复习之前知识点的需要,故撰写本教程,即是复习前面的知识点也是作为博客的补充 1.0 文件夹的创建 创建一个STM32项目为模版工程,问价夹下分别包含4个子文件夹,一个是Librar…...

JMH324-免费【最后一战LOL】MOBA竞技版本+单机一键端+视频教程+文本教程
资源介绍: 修改前打开【D:\ZHServer】文件夹里的【[1]一键启动.bat】,游戏不要打开,否则修改失败。 修改完以后重启架设程序才会生效。 fball_gamedb1数据库——gameuser数据表 obj_name 角色名 obj_lv 等级 obj_diamond 钻石 obj_gold 8…...

WPF UI 3D 多轴 机械臂 stl 模型UI交互
1、三维插件环境调整 2、动态模型材质处理 3、动态模型鼠标交互 4、模型旋转基本思路 5、六轴机械臂节点旋转处理 6、更多HelixToolkit插件处理案例 7、快速对接Blender模型 鼠标交互(没有强调场景的变换) 鼠标命中测试(HitTest 不推荐&…...

《金山 WPS AI 2.0:重塑办公未来的智能引擎》
AITOP100平台获悉,在 2024 世界人工智能大会这一科技盛宴上,金山办公以其前瞻性的视野和创新的技术,正式发布了 WPS AI 2.0,犹如一颗璀璨的星辰,照亮了智能办公的新征程,同时首次公开的金山政务办公模型 1.…...

RT2-使用NLP的方式去训练机器人控制器
目标 研究在网络数据上训练的视觉语言模型也可以直接结合到端到端的机器人控制中,提升泛化性以及获得突出的语义推理;使得单个的端到端训练模型可以同时学习从机器人观测到动作的映射,这个过程可以受益于基于网络上的语言和视觉语言数据的预训…...
VisActor vs ECharts: 哪个更适合你的数据可视化需求?
VisActor vs ECharts: 哪个更适合你的数据可视化需求? 在当今数据驱动的世界里,选择合适的数据可视化工具是至关重要的。ECharts作为广受欢迎的可视化库,已经在行业内拥有了长久的历史和广泛的用户基础。然而,VisActor作为新兴的…...

【QT中实现摄像头播放、以及视频录制】
学习分享 1、效果图2、camerathread.h3、camerathread.cpp4、mainwindow.h5、mainwindow.cpp6、main.cpp 1、效果图 2、camerathread.h #ifndef CAMERATHREAD_H #define CAMERATHREAD_H#include <QObject> #include <QThread> #include <QDebug> #include &…...

el-table封装popver組件,点击列筛选行数据功能,支持筛选,搜索,排序功能
子组件: <template><div class"tableTool" ref"tableTool" click.stop><el-button click"shengFnc">升序</el-button><el-button click"jiangFnc">降序</el-button><el-input v-m…...

基于DPU的云原生计算资源共池管理解决方案
1. 方案背景和挑战 在传统的云环境中,通常存在着不同的技术栈,支撑多样化的计算服务,具体如下: ① OpenStack环境与虚拟化云主机及裸金属服务 OpenStack是一个开源的云计算管理平台项目,它提供了部署和管理大规模计…...
Bugly并非无所不能
在 iOS 应用因为内存占用过大而被系统 killed 的情况下,Bugly 以及大多数崩溃报告工具是无法捕获到这种类型的崩溃信息的。原因在于,当系统由于内存压力过大而终止应用时,是直接将应用进程杀死,不会触发常规的崩溃处理流程&#x…...

2024年信息系统项目管理师1批次上午客观题参考答案及解析(3)
51、探索各种选项,权衡包括时间与成本、质量与成本、风险与进度、进度与质量等多种因素,在整个过程中,舍弃无效或次优的替代方案,这种不确定性应对方法是()。 A.集合设计 B.坚韧性 C.多种结果…...

YOLOv8改进 | 注意力机制 | 对密集和小目标友好的EVAblock 【原理 + 完整代码】
秋招面试专栏推荐 :深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡 专栏目录 :《YOLOv8改进有效…...

高效前端开发:解密pnpm的存储与链接
什么是pnpm PNPM(Performant NPM)是一种快速且节省磁盘空间的包管理工具。相较于其他包管理器如NPM和Yarn,PNPM通过独特的存储机制和链接技术解决了许多常见的问题。以下是PNPM如何避免这些问题以及其关键技术的详细介绍。 特性 PNPM Store…...

设置单实例Apache HTTP服务器
配置仓库 [rootlocalhost ~]# cd /etc/yum.repos.d/ [rootlocalhost yum.repos.d]# vi rpm.repo仓库代码: [BaseOS] nameBaseOS baseurl/mnt/BaseOS enabled1 gpgcheck0[AppStream] nameAppStream baseurl/mnt/AppStream enabled1 gpgcheck0挂载 [rootlocalhost …...

Python | Leetcode Python题解之第221题最大正方形
题目: 题解: class Solution:def maximalSquare(self, matrix: List[List[str]]) -> int:if len(matrix) 0 or len(matrix[0]) 0:return 0maxSide 0rows, columns len(matrix), len(matrix[0])dp [[0] * columns for _ in range(rows)]for i in…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...

Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...

听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...

GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...
【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error
在前端开发中,JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作(如 Promise、async/await 等),开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝(r…...