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

【LeetCode 题解】算法:29.两数相除

在算法的世界里,常常会出现一些打破常规、挑战思维的题目。LeetCode 第 29 题 “两数相除” 便是其中之一。这道题不仅要求我们在不能使用乘法、除法和取余运算的前提下实现两数相除,还需要处理 32 位有符号整数的溢出问题,对编程者的逻辑思维和代码实现能力提出了较高要求。接下来,就让我们一起剖析这道题的解题思路和实现方法。​

一、深入剖析题目要求​

1. 运算限制​

题目明确禁止使用乘法、除法和取余运算。这意味着我们需要另辟蹊径,借助其他数学运算和编程技巧来实现相除的功能。​

2. 结果截断​

整数除法需向零截断,即舍去小数部分。比如,8.345截断为8,-2.7335截断为-2。​

3. 溢出处理​

由于环境只能存储 32 位有符号整数,范围是[-2^31, 2^31 - 1]。因此,计算结果若超出这个范围,就需要返回相应的边界值。​

二、解题思路探索​

1. 朴素减法方案​

最容易想到的方法是反复从被除数中减去除数,通过统计相减的次数得到商。以10 / 3为例,计算过程如下:​

10 - 3 = 7 (第1次)​

7 - 3 = 4 (第2次)​

4 - 3 = 1 (第3次)​

一共减了 3 次,所以商为 3。然而,当被除数非常大,除数非常小时,这种方法的时间复杂度会变得很高,效率极其低下。​

2. 倍增优化方案​

为了提升效率,我们可以采用倍增的思想。每次尝试减去除数的倍数,而不是固定减去一个除数。例如,在计算10 / 3时:​

首先,我们判断10是否大于3 * 2(即6),若大于,就减去6,此时相当于一次减去了 2 个除数。然后,再从剩余的10 - 6 = 4中继续计算。通过这种方式,能够大幅减少运算次数。​

3. 位运算加速方案​

计算机在处理二进制数据时,位运算的速度非常快。在二进制中,左移一位相当于乘以 2,右移一位相当于除以 2。利用这一特性,我们可以通过左移除数,快速找到接近被除数的数值,再进行减法操作,从而进一步提升计算效率。​

三、Java 代码实现​

public class DivideTwoIntegers {​public int divide(int dividend, int divisor) {​// 处理除数为零的情况​if (divisor == 0) {​throw new IllegalArgumentException("除数不能为零");​}​​// 判断结果的正负​boolean isNegative = (dividend < 0) ^ (divisor < 0);​​// 将被除数和除数转换为负数,避免正数溢出问题​long dividendLong = convertToNegative(dividend);​long divisorLong = convertToNegative(divisor);​​// 执行核心计算​int result = calculateQuotient(dividendLong, divisorLong);​​// 根据结果的正负返回相应值,并处理溢出​return isNegative? handleNegativeResult(result) : handlePositiveResult(result);​}​​private long convertToNegative(int num) {​return num == Integer.MIN_VALUE? num : -Math.abs(num);​}​​private int calculateQuotient(long dividendLong, long divisorLong) {​int result = 0;​while (dividendLong <= divisorLong) {​long temp = divisorLong;​int multiple = 1;​while (dividendLong <= temp << 1) {​temp <<= 1;​multiple <<= 1;​}​dividendLong -= temp;​result += multiple;​}​return result;​}​​private int handleNegativeResult(int result) {​return result < Integer.MIN_VALUE? Integer.MIN_VALUE : -result;​}​​private int handlePositiveResult(int result) {​return result > Integer.MAX_VALUE? Integer.MAX_VALUE : result;​}​}​​

四、代码详细解析​

1. divide方法​

该方法是整个程序的入口,负责协调各个部分的逻辑。首先,检查除数是否为零,若为零则抛出异常。接着,通过异或运算判断结果的正负。为了避免在处理正数时因Integer.MIN_VALUE取相反数导致溢出,将被除数和除数转换为负数。之后,调用calculateQuotient方法进行核心计算,最后根据结果的正负进行相应处理,确保结果在 32 位有符号整数的范围内。​

2. convertToNegative方法​

此方法将传入的整数转换为负数。如果传入的数是Integer.MIN_VALUE,由于其取相反数会溢出,所以直接返回该值。否则,通过-Math.abs(num)将其转换为负数。​

3. calculateQuotient方法​

这是实现相除运算的核心方法。通过外层while循环,不断从被除数中减去合适倍数的除数。内层while循环利用位运算<<找到最大的可以减去的倍数,每次减去相应倍数的除数后,将倍数累加到结果中。​

4. handleNegativeResult和handlePositiveResult方法​

这两个方法分别处理计算结果为负数和正数的情况,确保结果不会超出 32 位有符号整数的取值范围。​

五、代码测试​

为了验证代码的正确性,我们可以编写测试用例:​

public class Main {​public static void main(String[] args) {​DivideTwoIntegers solution = new DivideTwoIntegers();​System.out.println(solution.divide(10, 3)); // 输出: 3​System.out.println(solution.divide(7, -3)); // 输出: -2​System.out.println(solution.divide(0, 5)); // 可以正常处理被除数为零的情况,输出: 0​System.out.println(solution.divide(1, 1)); // 常规正数测试,输出: 1​System.out.println(solution.divide(-1, -1)); // 常规负数测试,输出: 1​}​}​​

六、复杂度分析​

1. 时间复杂度​

在最坏情况下,时间复杂度为O(log n),其中n为被除数的绝对值。因为每次通过位运算<<找到可以减去的最大倍数,相当于将问题规模减半。​

2. 空间复杂度​

空间复杂度为O(1),在计算过程中,只使用了有限的额外空间,没有随着输入规模的增加而增加。

 

感谢各位的阅读,后续将持续给大家讲解力扣中的算法题和数据库题,如果觉得这篇内容对你有帮助,别忘了点赞和关注,后续还有更多精彩的算法解析与你分享!

 

相关文章:

【LeetCode 题解】算法:29.两数相除

在算法的世界里&#xff0c;常常会出现一些打破常规、挑战思维的题目。LeetCode 第 29 题 “两数相除” 便是其中之一。这道题不仅要求我们在不能使用乘法、除法和取余运算的前提下实现两数相除&#xff0c;还需要处理 32 位有符号整数的溢出问题&#xff0c;对编程者的逻辑思维…...

打包python文件生成exe

下载PyInstaller 官网 pip install pyinstaller验证是否安装成功 pyinstaller --version打包 pyinstaller "C:\Documents and Settings\project\myscript.py"会生成.spec,build,dist三项&#xff0c;其中build,dist为文件夹&#xff0c;dist是最后的可执行文件&a…...

【NLP】13. NLP推理方法详解 --- 穷举和贪心搜索

NLP推理方法详解 — 穷举和贪心搜索 在自然语言处理&#xff08;NLP&#xff09;任务中&#xff0c;推理&#xff08;Inference&#xff09;是指在给定模型的情况下&#xff0c;找到最可能的输出序列。由于模型通常是神经网络&#xff0c;它会为每个可能的输出分配一个概率&am…...

Redis延时队列在订单超时未报到场景的应用分享

一、引言 在电商、医疗预约等众多业务场景中&#xff0c;经常会遇到需要处理超时任务的情况。比如医疗预约订单&#xff0c;如果患者在支付成功后&#xff0c;到了预约结束时间还未报到&#xff0c;系统需要自动取消订单。为了实现这样的功能&#xff0c;我们可以利用 Redis 延…...

精心整理-2024最新网络安全-信息安全全套资料(学习路线、教程笔记、工具软件、面试文档).zip

2024最新网络安全-信息安全全套资料&#xff08;学习路线、教程笔记、工具软件、面试文档&#xff09;&#xff0c;视频教程文档资料共55GB。 一、网络安全-信息安全学习路线 0、网络安全-信息安全思维导图.jpg 1、网络安全大师课 V2024.pdf 2、网络安全行业白皮书.pdf 3、网络…...

多人协同进行qt应用程序开发应该注意什么?

多人协同进行Qt应用程序开发的注意事项 多人协同开发Qt应用程序时&#xff0c;需要注意以下几个关键方面以确保开发效率和代码质量&#xff1a; 1. 代码版本控制 使用Git&#xff1a;建立合理的分支策略&#xff08;如Git Flow&#xff09;.gitignore配置&#xff1a;确保忽…...

8.4考研408简单选择排序与堆排序知识点深度解析

考研408「简单选择排序与堆排序」知识点全解析 一、简单选择排序 1.1 定义与核心思想 简单选择排序&#xff08;Selection Sort&#xff09;是一种选择排序算法&#xff0c;其核心思想是&#xff1a; 每趟选择&#xff1a;从待排序序列中选择最小&#xff08;或最大&#x…...

C++中ShellExecute函数使用方法说明,如果一开始参数为隐藏,后面还能再显示出来吗

文章目录 一、ShellExecute基础用法函数原型关键参数 nShowCmd示例代码&#xff1a;启动程序并隐藏窗口 二、隐藏后能否重新显示窗口直接答案 三、实现隐藏后显示窗口的步骤1. 获取目标窗口句柄2. 显示窗口 四、完整流程示例五、注意事项六、总结 在C中使用ShellExecute函数时&…...

MySQL数据库精研之旅第五期:CRUD的趣味探索(上)

专栏&#xff1a;MySQL数据库成长记 个人主页&#xff1a;手握风云 目录 一、CRUD简介 二、Create新增 2.1. 语法 2.2. 示例 三、Retrieve检索 3.1. 语法 3.2. 示例 一、CRUD简介 CURD是对数据库中的记录进行基本的增删改查操作&#xff1a;Create(创建)、Retrieve(检索…...

【文件上传】✈️大文件的上传服务器的简单实现

&#x1f4a5;&#x1f4a5;✈️✈️欢迎阅读本文章❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;本篇文章阅读大约耗时五分钟。 ⛳️motto&#xff1a;不积跬步、无以千里 &#x1f4cb;&#x1f4cb;&#x1f4cb;本文目录如下&#xff1a;&#x1f381;&#x1f381;&a…...

Windows DOS窗口12个命令

DOS 命令是指在 Windows 命令提示符&#xff08;CMD&#xff09;中使用的命令行工具&#xff0c;源于早期的 Disk Operating System。虽然现代 Windows 系统更多使用图形界面&#xff0c;但命令提示符仍然是测试人员的重要工具。测试人员通常需要执行文件操作、测试网络连接、监…...

AI加Python的文本数据情感分析流程效果展示与代码实现

本文所使用数据来自于梯田景区评价数据。 一、数据预处理 数据清洗 去除重复值、空值及无关字符(如表情符号、特殊符号等)。 提取中文文本,过滤非中文字符。 统一文本格式(如全角转半角、繁体转简体)。 中文分词与去停用词 使用 jieba 分词工具进行分词。 加载自定义词…...

Go语言手动内存对齐的四大场景与实践指南

Go语言手动内存对齐的四大场景与实践指南 引言&#xff1a;Go的内存对齐机制 Go语言通过编译器自动处理内存对齐问题&#xff0c;开发者通常无需关心底层细节。然而&#xff0c;在特定场景下&#xff0c;手动干预内存对齐是避免程序崩溃或数据错乱的必要操作。本文将深入探讨G…...

PDF多表格结构识别与跨表语义对齐:基于对抗迁移的鲁棒相似度度量模型

文章目录 一. 项目结构二.流程分析2.1 批处理器核心代码解析 三. 跨页表格相似度匹配原理3.1 表头内容相似度-特征向量归一化3.2 表头内容相似度-余弦相似度3.3 定时缓存清理 ocr扫描有其局限性。对于pdf文本类型这种pdfbox&#xff0c;aspose-pdf&#xff0c;spire直接提取文本…...

docker启动nacos+redis+seata

docker启动nacos 最新版本的nacos需要再启动的时候设置mysql的一些属性&#xff0c;【也可以先启动nacos&#xff0c;再到配置文件中找到application.yml设置mysql的一些属性】。 1.如果直接启动nacos设置的mysql我们需要确定两个容器的ip都是一样的。 查看mysql容器中的ip命令…...

从 select 到 epoll:拆解 I/O 多路复用的演进与实战

目录 一、引言&#xff1a;为什么需要 I/O 多路复用&#xff1f; 二、select 1.函数介绍 2.原理 3.样例代码 4.优缺点总结 三、poll 1.函数介绍 2.样例代码 3.优缺点总结 四、epoll 1.函数介绍 2.原理 3.LT和ET两种工作模式 4.优缺点总结 五、核心机制对比&…...

Go后端架构探索:从 MVC 到 DDD 的演进之路

Go语言 MVC 与 DDD 分层架构详细对比 MVC和DDD是后台开发两种流行的分层架构思想&#xff0c;MVC&#xff08;Model-View-Controller&#xff09;是一种设计模式&#xff0c;主要用于分离用户界面、业务逻辑和数据模型&#xff0c;便于分层解耦&#xff0c;而DDD&#xff08;领…...

【力扣hot100题】(017)矩阵置零

还是挺简单的&#xff0c;使用哈希表记录需要置换的行列即可&#xff0c;这样就可以避免重复节省时间。 class Solution { public:void setZeroes(vector<vector<int>>& matrix) {unordered_set<int> row;unordered_set<int> line;for(int i0;i&l…...

One Commander 3,文件管理新体验

One Commander 3 是一款集多功能于一体 Windows 10/11的文件管理工具&#xff0c;其设计目的在于为用户带来多元化的操作体验。这款工具通过支持多栏界面布局&#xff0c;让用户能够迅速且高效地组织和管理文件。此外&#xff0c;它还提供了多主题选项和多种图标集&#xff0c;…...

Ubuntu 下 nginx-1.24.0 源码分析

main 函数在 src\core\nginx.c int ngx_cdecl main(int argc, char *const *argv) {ngx_buf_t *b;ngx_log_t *log;ngx_uint_t i;ngx_cycle_t *cycle, init_cycle;ngx_conf_dump_t *cd;ngx_core_conf_t *ccf;ngx_debug_init();if (ngx_strerror_in…...

c# ftp上传下载 帮助类

工作中FTP的上传和下载还是很常用的。如下载打标数据,上传打标结果等。 这个类常用方法都有了:上传,下载,判断文件夹是否存在,创建文件夹,获取当前目录下文件列表(不包括文件夹) ,获取当前目录下文件列表(不包括文件夹) ,获取FTP文件列表(包括文件夹), 获取当前目…...

Java进阶——静态代理与动态代理

代理模式是一种常用的设计模式&#xff0c;为其他对象提供一种代理以控制对这个对象的访问。代理模式就像是一个中间人&#xff0c;客户端通过代理来间接访问目标对象&#xff0c;可以在不修改目标对象的基础上&#xff0c;对目标对象的功能进行增强或扩展。代理模式主要分为静…...

VS Code 中 .history`文件的来源与 .gitignore`的正确使用

引言 在使用 VS Code 进行 Git 版本控制时&#xff0c;有时会发现项目中多出一个 .history 目录&#xff0c;并被 Git 识别为未跟踪文件。本文将解释 .history 的来源&#xff0c;并提供 .gitignore 的正确配置方法&#xff0c;确保开发环境的整洁性。 1. .history 文件的来源…...

非手性分子发光有妙招:借液晶之力,实现高不对称圆偏振发光

*本文只做阅读笔记分享* 一、圆偏振发光研究背景与挑战 圆偏振发光&#xff08;CPL&#xff09;材料在3D显示、光电器件等领域大有用处&#xff0c;衡量它的一个重要指标是不对称发光因子&#xff08;glum&#xff09;。早期CPL材料的glum值低&#xff0c;限制了实际应用。为…...

解释器模式_行为型_GOF23

解释器模式 解释器模式&#xff08;Interpreter Pattern&#xff09;是一种行为型设计模式&#xff0c;核心思想是定义语言的文法规则&#xff0c;并构建一个解释器来解析和执行该语言中的表达式。它类似于“翻译器”——将符合特定语法规则的文本&#xff08;如数学公式、脚本…...

OTN(Optical Transport Network)详解

OTN&#xff08;光传送网&#xff09;是一种基于**波分复用&#xff08;WDM&#xff09;**的大容量光传输技术&#xff0c;结合了SDH的运维管理优势和WDM的高带宽特性&#xff0c;广泛应用于骨干网、城域核心层及数据中心互联&#xff08;DCI&#xff09;。 1. OTN 的基本概念 …...

YOLOv8+ Deepsort+Pyqt5车速检测系统

该系统通过YOLOv8进行高效的目标检测与分割&#xff0c;结合DeepSORT算法完成目标的实时跟踪&#xff0c;并利用GPU加速技术提升处理速度。系统支持模块化设计&#xff0c;可导入其他权重文件以适应不同场景需求&#xff0c;同时提供自定义配置选项&#xff0c;如显示标签和保存…...

【干货】前端实现文件保存总结

⚠️⚠️文前推荐一下&#x1f449; 前端必备工具推荐网站(图床、API和ChatAI、智能AI简历、AI思维导图神器等实用工具): 站点入口&#xff1a;http://luckycola.com.cn/ 前端实现文件保存实现总结 在Web开发中&#xff0c;文件下载是常见的交互需求。本文将系统总结前端实现文…...

并发编程之FutureTask.get()阻塞陷阱:深度解析线程池CPU飚高问题排查与解决方案

FutureTask.get方法阻塞陷阱&#xff1a;深度解析线程池CPU飚高问题排查与解决方法 FutureTask.get()方法阻塞陷阱&#xff1a;深度解析线程池CPU飚高问题排查与解决方法1、情景复现1.1 线程池工作原理1.2 业务场景模拟1.3 运行结果1.4 发现问题&#xff1a;线程池没有被关闭1.…...

DGNN-YOLO:面向遮挡小目标的动态图神经网络检测与追踪方法解析

一、算法结构与核心贡献 1.1 文章结构 采用经典五段式结构: ​引言:分析智能交通系统(ITS)中小目标检测与追踪的挑战,提出研究动机。​相关工作:综述小目标检测(YOLO系列、Faster R-CNN)、目标追踪(SORT、Transformer)和图神经网络(GNN)的进展。​方法论:提出DG…...