力扣29(java)-两数相除(中等)
题目:
给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。
返回被除数 dividend 除以除数 divisor 得到的商。
整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2
示例 1:
输入: dividend = 10, divisor = 3
输出: 3
解释: 10/3 = truncate(3.33333..) = truncate(3) = 3
示例 2:
输入: dividend = 7, divisor = -3
输出: -2
解释: 7/-3 = truncate(-2.33333..) = -2
提示:
- 被除数和除数均为 32 位有符号整数。
- 除数不为 0。
- 假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231 − 1]。本题中,如果除法结果溢出,则返回 231 − 1。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/divide-two-integers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:
参考各位大佬是解题思路,这里记录一下
运用的是【翻倍循环相减】法,即对除数divisor不断翻倍,找到最接近且小于被除数dividend的最大除数,然后让当前被除数减去最大除数并记录当前倍数,然后对剩余的被除数不断重复以上的操作,直至当前被除数小于除数,所有倍数求和即为商quotient。
例如:
①23 / 3
1.计算3的2x的最大值(不超过23),对3不断的翻倍,3-->6-->12-->24,此时的24超过23,即用23-12 = 11,11作为新的被除数,3 * 2 2 = 12;
2.计算3的2x的最大值(不超过11),对3不断的翻倍,3-->6-->12,此时的11超过6,即用11-6 = 5,5作为新的被除数,3 * 2 1 = 6;
3.计算3的2x的最大值(不超过5),对3不断的翻倍,3-->6,此时的6超过5,即用6-5 = 1,1作为新的被除数,3 * 2 0 = 3;
4.新的被除数1已经小于3了,计算结束,商为22+21+20=7,即可得知23 / 3 = 7(省略小数部分);
②97 / 5
1.计算5的2x的最大值(不超过97),对5不断的翻倍,5-->10-->20-->40-->80-->160,此时的160超过97,即用97-80 = 17,17作为新的被除数,5 * 2 4 = 80;
2.计算5的2x的最大值(不超过17),对5不断的翻倍,5-->10-->20,此时的20超过17,即用17-10 = 7,7作为新的被除数,5 * 2 1 = 10;
3.计算5的2x的最大值(不超过7),对5不断的翻倍,5-->10,此时的10超过7,即用7-5 = 2,2作为新的被除数,5 * 2 0 = 5;
4.新的被除数2已经小于5了,计算结束,商为24 + 21+20=19,即可得知97 / 5 = 19(省略小数部分);
再看题目结合三个提示部分,翻译过来即为:
1.不能使用long;
2.不能使用乘法、除法和 mod 运算符;
3.考虑溢出问题。
首先不使用long:在32位系统上int和long的取值范围是一样的,int取值范围:-2147483648 ~ 2147483647,long取值范围:-2147483648 ~ 2147483647,故将所有数转化到[−231, 0]来进行运算,以避免负数转正数时的溢出问题。
其次不能使用乘法、除法和 mod 运算符:那就使用加法、减法、位运算等等;
最后溢出问题:主要是被除数为 Integer.MIN_VALUE 而除数为 -1 的情况,−231 / -1 = 231,因为负数的最小值的绝对值比正数的最大值大 1,所以这样算出来会溢出,这种情况需要特殊处理。
最终解题思路分为三步:
1.对边界情况进行特殊判断;
2.将被除数和除数都转换成负数,并记录最终结果的符号;
3.逐步增大除数来逼近被除数;
代码:
1 class Solution {
2 public int divide(int dividend, int divisor) {
3 //溢出情况
4 if(dividend == Integer.MIN_VALUE && divisor == -1){
5 return Integer.MAX_VALUE;
6 }
7 //记录结果的符号
8 int sign = -1;
9 //如果为两正或两负,即符号为正
10 if((dividend > 0 && divisor > 0) || (dividend < 0 && divisor < 0)){
11 sign = 1;
12 }
13 //将被除数和除数均转换成负数
14 dividend = dividend > 0 ? -dividend : dividend;
15 divisor = divisor > 0 ? -divisor : divisor;
16 //设置一个变量保存商的值
17 int quotient = 0;
18 //负数的比较与正数相反,模拟倍数的过程
19 while(dividend <= divisor){
20 //定义一个中间变量temp来保存过渡的除数的倍数
21 //定义一个count来记录倍数2^x
22 int temp = divisor,count = 1;
23 //temp + temp可能会导致整型溢出
24 //最小的int负数是 -2^31(0x80000000),它的一半是 -2³¹/2=-2³⁰(-1073741824)
25 //但因为是负数故 temp >= -1073741824
26 while(temp >=-1073741824 && (temp + temp >= dividend)){
27 temp += temp;
28 count += count;
29 }
30 //找新的被除数
31 dividend -= temp;
32 quotient += count;
33 }
34 return sign < 0 ? -quotient : quotient;
35
36 }
37 }

力扣29(java)-两数相除(中等)的更多相关文章
- Leetcode(29)-两数相除
给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商. 示例 1: 输 ...
- 【leetcode 29】 两数相除(中等)
题目描述 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商. 整数 ...
- Java实现 LeetCode 29 两数相除
29. 两数相除 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商 ...
- [LeetCode] 29. Divide Two Integers 两数相除
Given two integers dividend and divisor, divide two integers without using multiplication, division ...
- Leetcode 29.两数相除 By Python
给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商. 示例 1: 输 ...
- LeetCode(29): 两数相除
Medium! 题目描述: 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor ...
- LeetCode 29 - 两数相除 - [位运算]
题目链接:https://leetcode-cn.com/problems/divide-two-integers/description/ 给定两个整数,被除数 dividend 和除数 divis ...
- leetcode 29 两数相除
问题描述 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商. 示例 ...
- [LeetCode]29 两数相除和一个小坑点
给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商. 示例 1: 输 ...
- [LeetCode] Divide Two Integers 两数相除
Divide two integers without using multiplication, division and mod operator. If it is overflow, retu ...
随机推荐
- python tcp socket 源码分享
服务端的源码: import socketserver class Handler_TCPServer(socketserver.BaseRequestHandler): ""&q ...
- C++ 赋值运算符和拷贝构造函数
拷贝构造函数 class Foo{ public: Foo(); Foo(const Foo&); //自己定义的拷贝构造函数 }; 如果不自己定义,编译器会自己合成一个默认拷贝构造函数: c ...
- MySQL(表相关操作)
一 存储引擎 日常生活中文件格式有很多,并且针对不同的文件格式会有对应不同存储方式 和处理机制(txt.word) 针对不同的数据应该有对应的不同的处理机制来存储 存储引擎就是不同的处理机制 MySQ ...
- Smtp Oauth With Python
我的博客园:https://www.cnblogs.com/CQman/ GitHub #基于Python语言的smtp Oauth 连接世纪互联运营的Office 365(或21V O365)的邮箱 ...
- 记录--关于无感刷新Token,我是这样子做的
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 什么是JWT JWT是全称是JSON WEB TOKEN,是一个开放标准,用于将各方数据信息作为JSON格式进行对象传递,可以对数据进行可 ...
- 神经网络——基于sklearn的参数介绍及应用
一.MLPClassifier&MLPRegressor参数和方法 参数说明(分类和回归参数一致): hidden_layer_sizes :例如hidden_layer_sizes=(50, ...
- 01-【HAL库】STM32实现串口打印
一.什么是串口 串口通讯(Serial Communication)是一种设备间非常常用的串行通讯方式,因为它简单便捷,因此大部分电子设备都支持该通讯方式,电子工程师在调试设备时也经常使用该通讯方式输 ...
- 【IOT安全】ASA5520基本知识和配置
本文主要介绍ASA5520防火墙的基本知识和配置 环境搭建 Linux eveng 5.17.8-eve-ng-uksm-wg+ #1 SMP PREEMPT Mon May 16 10:08:59 ...
- java 控制台 输出进度条
效果 代码 public static void main(String[] args) { int total = 100; for (int i = 0; i < total; i++) ...
- Oracle与Java JDBC数据类型对照
Oracle Database JDBC开发人员指南和参考 SQL Data Types JDBC Type Codes Standard Java Types Oracle Extension Ja ...