LeetCode_29_中等_两数相除

文章目录

  • 1. 题目
  • 2. 思路及代码实现详解(Python)
    • 2.1 位运算与二分查找


1. 题目

给你两个整数,被除数 d i v i d e n d dividend dividend 和除数 d i v i s o r divisor divisor。将两数相除,要求 不使用 乘法、除法和取余运算。

整数除法应该向零截断,也就是截去( t r u n c a t e truncate truncate)其小数部分。例如, 8.345 8.345 8.345 将被截断为 8 8 8 − 2.7335 -2.7335 2.7335 将被截断至 − 2 -2 2

返回被除数 d i v i d e n d dividend dividend 除以除数 d i v i s o r divisor divisor 得到的

注意:假设我们的环境只能存储 32 32 32 有符号整数,其数值范围是 [ − 2 31 , 2 31 − 1 ] [−2^{31}, 2^{31} − 1] [231,2311] 。本题中,如果商 严格大于 2 31 − 1 2^{31} − 1 2311 ,则返回 2 31 − 1 2^{31} − 1 2311 ;如果商 严格小于 − 2 31 -2^{31} 231 ,则返回 − 2 31 -2^{31} 231

示例 1:

输入: d i v i d e n d = 10 , d i v i s o r = 3 dividend = 10, divisor = 3 dividend=10,divisor=3
输出: 3 3 3
解释: 10 / 3 = 3.33333.. 10/3 = 3.33333.. 10/3=3.33333..,向零截断后得到 3 3 3

示例 2:

输入: d i v i d e n d = 7 , d i v i s o r = − 3 dividend = 7, divisor = -3 dividend=7,divisor=3
输出: − 2 -2 2
解释: 7 / − 3 = − 2.33333.. 7/-3 = -2.33333.. 7/3=2.33333.. ,向零截断后得到 − 2 -2 2


提示

  • − 2 31 < = d i v i d e n d , d i v i s o r < = 2 31 − 1 -2^{31} <= dividend, divisor <= 2^{31} - 1 231<=dividend,divisor<=2311
  • d i v i s o r ≠ 0 divisor \neq 0 divisor=0

2. 思路及代码实现详解(Python)

由于题目规定了「只能存储 32 32 32 位整数」,因此不能使用任何 64 64 64 位整数,尽管这会极大增加我们编码难度。对于可能造成溢出的问题,在编码之前,需要先对于溢出或者容易出错的边界情况进行讨论,即在某一边界上,继续进行操作后会溢出,这个边界取决于我们会采取何种操作:

  • 当被除数为 32 32 32 位有符号整数的最小值 − 2 31 −2^{31} 231 时:
    • 如果除数为 1 1 1,那么我们可以直接返回答案 − 2 31 −2^{31} 231
    • 如果除数为 − 1 −1 1,那么答案为 2 31 2^{31} 231,这时结果产生了溢出。此时我们需要返回 2 31 − 1 2^{31}-1 2311
  • 当除数为 32 32 32 位有符号整数的最小值 − 2 31 −2^{31} 231 时:
    • 如果被除数同样为 − 2 31 −2^{31} 231,那么我们可以直接返回答案 1 1 1
    • 对于其余的情况,我们返回答案 0 0 0,因为得到的商不大于 1 1 1 时截断小数部分得到 0 0 0
  • 当被除数为 0 0 0 时,不论除数是多少,都直接返回答案 0 0 0

对于其他的一般情况,根据除数和被除数的符号,我们需要考虑 4 4 4 种不同的符号组合。因此,为了方便编码,我们可以将被除数或者除数取相反数,使得它们符号相同。

  • 如果将被除数和除数都变为正数,那么可能会导致溢出。例如当被除数为 − 2 31 −2^{31} 231 时,它的相反数 2 31 2^{31} 231 产生了溢出。
  • 如果将被除数和除数都变为负数,这样在取相反数时就不会有溢出的问题,而结果溢出也只有 ( − 2 31 ) / ( − 1 ) (-2^{31})/(-1) (231)/(1) 这种情况。

如果我们恰好只将被除数和除数中的一个变为了正数,那么在返回答案之前,我们需要对答案也取相反数。

2.1 位运算与二分查找

上面的讨论考虑了数值溢出的问题,以及几种可以直接返回结果的特殊情况。我们记被除数为 X X X,除数为 Y Y Y,且此时两者都被我们转为负数,我们要求的是 X / Y X/Y X/Y 的结果 Z Z Z,显然, Z Z Z 的值一定为整数或 0 0 0

因为 Y Y Y 为负值,随着 Z Z Z 增大乘积减小,容易得到: Z × Y ≥ X > ( Z + 1 ) × Y Z\times Y\geq X\gt (Z+1)\times Y Z×YX>(Z+1)×Y,因此我们求商就是找到最大的使得 Z × Y > X Z\times Y\gt X Z×Y>X 成立的 Z Z Z。而由于不能使用乘法运算,就需要用到快速乘的算法。其实就是通过二分查找和位移运算来实现所谓的 乘法,但其本质是加法的快速运算和判断。

具体的代码如下,判断不等式的次数为 O ( l o g C ) O(logC) O(logC),而判断函数的搜索范围是 32 32 32 位整数的全部范围,最差情况下也要 O ( l o g C ) O(logC) O(logC) 的判断次数,因此总的时间复杂度为 O ( l o g 2 C ) O(log^2C) O(log2C),而空间复杂度为 O ( 1 ) O(1) O(1),仅存储若干的上下界信息。

class Solution:def divide(self, dividend: int, divisor: int) -> int:INT_MIN, INT_MAX = -2**31, 2**31 - 1# 考虑被除数为最小值的情况if dividend == INT_MIN:if divisor == 1:return INT_MINif divisor == -1:return INT_MAX# 考虑除数为最小值的情况if divisor == INT_MIN:return 1 if dividend == INT_MIN else 0# 考虑被除数为 0 的情况if dividend == 0:return 0# 一般情况,使用二分查找# 将所有的正数取相反数,这样就只需要考虑一种情况rev = Falseif dividend > 0:dividend = -dividendrev = not revif divisor > 0:divisor = -divisorrev = not rev# 快速乘def quickAdd(y: int, z: int, x: int) -> bool:# x 和 y 是负数,z 是正数# 需要判断 z * y >= x 是否成立result, add = 0, ywhile z > 0:if (z & 1) == 1:    # 需要保证 result + add >= xif result < x - add:return Falseresult += addif z != 1:# 需要保证 add + add >= xif add < x - add:return Falseadd += add# 不能使用除法,退位z >>= 1return Trueleft, right, ans = 1, INT_MAX, 0while left <= right:# 注意溢出,并且不能使用除法mid = left + ((right - left) >> 1)check = quickAdd(divisor, mid, dividend)if check:ans = mid# 注意溢出if mid == INT_MAX:breakleft = mid + 1else:right = mid - 1return -ans if rev else ans

执行用时:45 ms
消耗内存:16.45 MB

题解来源:力扣官方题解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/754795.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

20240318uniapp怎么引用组件

在script中增加 import index from "/pages/index/index.vue" 把index直接整个作为一个组件引入 然后注册组件 在export default中增加 components: {index:index }, 注册了index组件&#xff0c;内容为import的index 然后就可以在template里使用 <index&…

机器人可反向驱动能力与力控架构

反向驱动性是电机传动系统的机械特性&#xff0c;它描述了运动是否可以轻松反转 。特别是&#xff0c;反向驱动能力取决于两个因素&#xff1a;传动运动效率和整体执行器机械阻抗。反向运动中传动装置的低运动效率意味着所施加的外力的大部分被运动反作用力抵消。然而&#xff…

Ubuntu 搭建gitlab服务器,及使用repo管理

一、GitLab安装与配置 GitLab 是一个用于仓库管理系统的开源项目&#xff0c;使用Git作为代码管理工具&#xff0c;并在此基础上搭建起来的Web服务。 1、安装Ubuntu系统&#xff08;这个教程很多&#xff0c;就不展开了&#xff09;。 2、安装gitlab社区版本&#xff0c;有需…

arm32机器的ubuntu1804的源突然不能update了

换成x86的官方源不行: Hit:1 http://archive.canonical.com/ubuntu bionic InRelease Get:2 http://archive.ubuntu.com/ubuntu bionic InRelease [242 kB] Get:3 http://archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB] Get:4 http://archive.ubuntu.com/ubu…

GAMES101 学习 2

Lecture 7&#xff1a;Shading 1(lllumination,Shading and Graphics Pipeline) Visibility / occlusion 解决可见性和遮挡的问题 可见性&#xff0c;Z-buffering Z-Buffer 深度缓存 Idea&#xff1a; Store current min. z-value for each sample (pixel)Needs an additi…

python学习3:unittest测试框架初学习

python内置测试框架 unittest&#xff08;xUnit家族成员 参考JUnit&#xff09;doctest&#xff1a; 假设被测试目标: def add(a,b):c a breturn c创建一个"test_同名"的文件夹 基本用法 1 创建测试用例 1 定义TestCase的子类 2 定义test_开头的方法 3 在方法…

vue-resource发送请求

导入依赖 终端输入 npm i vue-resource 使用插件 在main.js中应用插件 import Vue from "vue"; import App from "./App.vue" //引入插件 import vueResource from "vue-resource"; //使用插件 Vue.use(vueResource)new Vue({el:#app,render:h…

k8s工作节点主要模块

背景 k8s集群的worker节点作为主要的pod容器的运行节点&#xff0c;其上面有两个非常核心的模块组件&#xff0c;本文就来简单了解下 k8s工作节点主要模块 1.kublet组件&#xff0c;这个组件运行在工作节点上 1.1 它是一个负责这个节点所有pod运行的指挥官的角色&#xff0…

鸿蒙Harmony应用开发—ArkTS声明式开发(绘制组件:Line)

直线绘制组件。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 无 接口 Line(value?: {width?: string | number, height?: string | number}) 从API version 9开始&#xff0c;该接…

Twincat实现电机控制

不仅是控制系统的核心部分&#xff0c;而且能够将任何基于PC的系统转换为一个带有PLC、NC、CNC和机器人实时操作系统的实时控制系统。TwinCAT软件在工业自动化领域具有广泛的应用&#xff0c;特别是在机器人关节电机控制方面!!! 在机器人关节电机控制方面&#xff0c;TwinCAT通…

实验三 前端性能优化-CSS优化

仓库地址&#xff1a;bj-front: 前端性能与工程化 - Gitee.com 利用简写CSS属性和CSS浅选择器&#xff0c;贯彻DRY原则&#xff0c;来完成对页面的CSS的优化过程&#xff0c;通过避免不良实践&#xff0c; 以及使用高性能的CSS选择器、flexbox布局引擎和CSS过渡&#xff0c;提…

vue3 新特性defineOptions和defineModel

一、vue3.3 新特性defineOptions 在Vue3.3之前&#xff0c;组件的默认组件名为.vue单文件组件文件的名字&#xff0c;假如我们想修改组件名&#xff0c;则需要结合Options API进行修改。defineOptions的出现解决了这个问题。 这个宏可以用来直接在 <script setup> 中声明…

鸿蒙Harmony应用开发—ArkTS声明式开发(绘制组件:Shape)

绘制组件的父组件&#xff0c;父组件中会描述所有绘制组件均支持的通用属性。 1、绘制组件使用Shape作为父组件&#xff0c;实现类似SVG的效果。 2、绘制组件单独使用&#xff0c;用于在页面上绘制指定的图形。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有…

html5播放flv视频

参考&#xff1a;flv-h265 - npmHTML5 FLV Player. Latest version: 1.7.0, last published: 6 months ago. Start using flv-h265 in your project by running npm i flv-h265. There are no other projects in the npm registry using flv-h265.https://www.npmjs.com/packag…

高效备考2025年AMC8竞赛:吃透2000-2024年600道真题(免费送题)

我们继续来随机看五道AMC8的真题和解析&#xff0c;根据实践经验&#xff0c;对于想了解或者加AMC8美国数学竞赛的考生来说&#xff0c;吃透AMC8历年真题是备考更加科学、有效的方法之一。 即使不参加AMC8竞赛&#xff0c;吃透了历年真题600道和背后的知识体系&#xff0c;那么…

【linux】进程间通信1--管道

文章目录 进程间通信是什么&#xff1f;如何做&#xff1f; 管道匿名管道命名管道 进程间通信 是什么&#xff1f; 进程间通信&#xff08;Inter-Process Communication&#xff0c;IPC&#xff09;是指在操作系统中&#xff0c;不同的进程之间进行数据交换、信息传递和同步操…

人事管理系统|基于JSP+ Mysql+Java+ B/S结构的人事管理系统设计与实现(可运行源码+数据库+设计文档)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含java&#xff0c;ssm&#xff0c;springboot的平台设计与实现项目系统开发资源&#xff08;可…

LeetCode 热题 HOT 100(P11~P20)

系列文章&#xff1a; LeetCode 热题 HOT 100(P1~P10)-CSDN博客 LeetCode 热题 HOT 100(P11~P20)-CSDN博客 LC020valid_parentheses . - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&…

医疗器械经营许可证办理流程及申请流程有哪些?

1、证书内容差异&#xff1a; 1.医疗器械经营许可证应当载明许可证号码、法定代表人、负责人、住所、经营范围、仓库地址、发证部门、日期及有效期、公司名称等事项。 2.医疗器械生产经营管理注册证书应当载明编号、公司产品名称、法定代表人、住所、经营活动场所、业务发展方…

基于PyTorch的视频分类实战

1、数据集下载 官方链接&#xff1a;https://serre-lab.clps.brown.edu/resource/hmdb-a-large-human-motion-database/#Downloads 百度网盘连接&#xff1a; https://pan.baidu.com/s/1sSn--u_oLvTDjH-BgOAv_Q?pwdxsri 提取码: xsri 官方链接有详细的数据集介绍&#xf…