postgre非零相除等于0_LeetCode刷题实战29:两数相除
算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !
今天和大家聊的问题叫做 两数相除,我们先来看题面:
https://leetcode-cn.com/problems/divide-two-integers/
给定两个整数,被除数和除数,要求在不使用除法的情况下计算出两数的商
Given two integers dividend
and divisor
, divide two integers without using multiplication, division and mod operator.
Return the quotient after dividing dividend
by divisor
.
The integer division should truncate toward zero.
样例 1:
Input: dividend = 10, divisor = 3
Output: 3
样例 2:
Input: dividend = 7, divisor = -3
Output: -2
注意:
除数和被除数都在32位int的范围内
除数不为0
- 对于超界的情况返回
- Both dividend and divisor will be 32-bit signed integers.
- The divisor will never be 0.
- Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−, − 1]. For the purpose of this problem, assume that your function returns − 1 when the division result overflows.
题解
老规矩,我们依然从最简单的情况开始入手。我们都知道,在计算机内部,是二进制的,而二进制是只能进行加减的。所以所有的乘法和除法的操作其实最终都会转换为加减法来进行。对于这道题而言也是一样的,既然禁止我们使用除法,那么我们可以用减法来代替。
暴力
最简单的策略就是我们可以用一个循环去不停地减,然后用一个累加器计算到底执行了多少次减法,当不够减的时候则停止。整个流程非常简单,但是我们还需要考虑一下正负号的问题,按照排列组合来看,被除数和除数一共有4中正负号的情况。但我们并不需要考虑那么多,这四种情况可以简单地归并成是否同号两种,然后进一步分析又会发现是否同号的计算过程并没有差别,唯一会影响的只有最后结果的正负号。还有一点比较令人在意的是提示当中说的可能会超界的情况,我们来分析一下,其实会超界的可能性只有一个。那就是除以-1的情况,会得到,而32位int的正数范围最大是,所以我们需要在意这个问题。不过好在对于Python而言,int是没有范围的,所以可以忽略这个问题,只需要最后特判一下结果,但是对于C++和Java等语言而言,需要特殊处理,比如可以使用long long或者是全部转成负数。我们来总结一下上面的过程,我们可以先将除数和被除数全部转化为正数,然后用一个标记flag来记录它们是否同号。再计算完结果之后,需要判断一下结果的范围是否越界,如果越界返回。代码如下:
class Solution:def divide(self, dividend: int, divisor: int) -> int:# 判断是否同号 flag = (dividend > 0 and divisor > 0) or (dividend < 0 and divisor < 0) ret = 0# 全部赋值为正 dividend, divisor = abs(dividend), abs(divisor) start = 0# 模拟除法while start + divisor <= dividend: start += divisor ret += 1# 防止越界,注意只有正数才有可能越界return min(ret, (1 << 31) - 1) if flag else -ret
这个代码当然是没有问题的,但是如果你真的这么提交,那么一定会超时。原因也很简单,当除数非常小,比如是1的时候,那么我们的循环次数就是被除数的大小。当我们给定一个很大的被除数的时候,会超时就是显然的了。
二进制优化
接下来讲的这个算法很重要,是快速幂等许多算法的基础,由于本题当中不是进行的幂运算,所以不能称作是快速幂算法,一时间也没有什么好的名字,由于本质上是通过二进制的运算来优化,所以就称为二进制优化吧。在讲解算法之前,我们先来分析一下bad case出现的原因。之所以会超时,是因为有可能被除数非常小,比如是1,这个时候我们一位一位地减就非常耗时。那么很自然地可以想到,我们可不可以每次不是减去一个1,而是若干个1,最后把这些减去的数量加起来,是不是会比每次减去一个要更快一些呢?但是还有细节我们不清楚,我们怎么来确定这个每次应该减去的数量呢?如果确定了之后发现不够减,又应该怎么办呢?要回答上面这个问题,需要对二进制有比较深入的理解。我们先把刚才的问题放一放,来看一看二进制对于除法的解释。举个简单的例子,比如15 / 3 = 5。我们知道15等于5个3相乘,那么我们把它们都写成二进制。15的二进制是1111,3的二进制是0011,5的二进制是0101,我们重点来看这个5的二进制。5的二进制写成0101,展开的话会得到是,也就是说我们可以把15看成,这个式子写成是。也就是说我们可以把被除数看成是若干个2的幂乘上除数的和,这就把一个除法问题转化成了加法问题。同样我们把求解商转化成了求解商的二进制表达,二进制表达有了,最后的商无非是再进行一个求和累加即可。最后,我们来分析一下,为什么能够优化。因为题目当中已经限定了,除数和被除数都在32位的int范围。也就是说最多只有32个二进制位,那么我们的循环次数最多也就是32次。通过二进制优化,我们把原本一个的问题,降级成了,这两者之间差了不止一个数量级,当然要快得多。我们把上面这个思路写成代码,就可以得到答案:
class Solution:def divide(self, dividend: int, divisor: int) -> int:# 前面处理和之前一样 flag = (dividend > 0 and divisor > 0) or (dividend < 0 and divisor < 0) ret = 0 dividend, divisor = abs(dividend), abs(divisor)# 预处理二进制数组 binary = [0 for _ in range(33)]# 第0位即2的零次方乘上除数,所以就是除数本身 binary[0] = divisorfor i in range(1, 33):# 后面每一位是前面一位的两倍,因为二进制# << 是位运算左移操作,等价于*2,但是速度更快 binary[i] = binary[i-1] << 1for i in range(32, -1, -1):if binary[i] <= dividend: dividend -= binary[i]# 答案加上2^i ret += (1 << i)return min(ret, (1 << 31) - 1) if flag else -ret
这段代码不长,也没有用到什么特别牛哄哄的算法,无非是对二进制的一些运用。但是对于对二进制不够熟悉的初学者而言,想完全搞明白可能有些费劲,这也是很正常的。希望大家能够沉下心来好好理解,如果实在看不懂也没关系,在以后快速幂等算法当中,还会和它见面的。今天的文章就是这些,如果觉得有所收获,请顺手点个在看或者转发吧,你们的举手之劳对我来说很重要。
上期推文:
LeetCode1-20题汇总,速度收藏!LeetCode刷题实战21:合并两个有序链表LeetCode刷题实战23:合并K个升序链表LeetCode刷题实战24:两两交换链表中的节点LeetCode刷题实战25:K 个一组翻转链表
postgre非零相除等于0_LeetCode刷题实战29:两数相除相关推荐
- c语言两数相除等于小数多少,c语言程序两数相除精确到小数点后k位
题目: 输入两个整数m和n,及另一正整数k,计算m/n,结果精确到小数点后k位 1.问题分析与方案设计. 1.首先解决输入问题.题目要求输入三个整数m,n,k.所以定义input()函数,使输入的为正 ...
- leetcode 29.两数相除
leetcode 29.两数相除 题目描述 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 ...
- 【leedcode刷题1】两数之和
[leedcode刷题 1]两数之和 大家好,小生不才,从今天开始将自己刷题的过程记录在博客中,因为能力有限,所以如果有什么错的地方希望大家积极指正,不胜感激. 题目 给定一个整数数组 nums 和一 ...
- LeetCode高频题29. 两数相除:不用加减乘除号,求加法,减法,乘法,除法
LeetCode高频题29. 两数相除 提示:本题是系列LeetCode的150道高频题,你未来遇到的互联网大厂的笔试和面试考题,基本都是从这上面改编而来的题目 互联网大厂们在公司养了一大批ACM竞赛 ...
- LeetCode-中等-29. 两数相除
LeetCode-中等-29. 两数相除 题目 引用自:LeetCode-中等-29. 两数相除(如有侵权联系删除) 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不 ...
- Java实现 LeetCode 29 两数相除
29. 两数相除 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商 ...
- leetcode第29题python版两数相除
class Solution:"""29. 两数相除给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符.& ...
- LeetCode 27移除元素28实现strStr()29两数相除
维护幸苦,如有打卡欢迎关注公众号bigsai回复进群,如有帮助欢迎点赞支持! 移除元素 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长 ...
- leetcode —— 29. 两数相除
给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商. 整数除法的结果 ...
最新文章
- ping 命令还能这么玩?
- 后端:Java 中 10 大坑爹功能!
- [Jobdu] 题目1530:最长不重复子串
- vsftp服务器搭建
- 直设计map.html页面,map4.html
- python oop 实践_Python OOP示例?
- C# log4net App.config 配置系统未能初始化问题
- 【Linux】【操作】Linux操作集锦系列之一——定时任务
- 用python进行数据分析(二:数据处理)
- 许竹青、骆艾荣:数字城市的理念演化、主要类别及未来趋势研究
- exe制作成安装包,Inno Setup软件使用教程
- Failing OffsetCommit request since the consumer is not part of an active group
- blender 制作城市建筑模型
- 免费网站翻译整个文档并保留原格式
- 又一大佬加盟OpenAI!他还是姚班学霸陈立杰的导师
- 阿里主流开源框架大汇总
- 搭建ngrok服务器
- Netlify前端自动化部署服务
- python合并pdf_python如何将多个PDF进行合并
- html5公司年终抽奖程序源码按数字随机抽奖