力扣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 ...
随机推荐
- Istio中的核心资源及定义
Istio 的核心资源主要包括以下几种: 1. Gateway 用于建模边缘网关,可以为进入或离开网格的流量提供专用的入口和出口点.Gateway 定义了在网格边缘运行的负载均衡器,用于接收传入或传出 ...
- 谈谈Android中的消息提示那些坑
Android中的消息提示无非就那几种,弹个窗(Toast或SnackBar),或者是弹出个对话框(Dialog),最近在使用的时候也是遇到了问题,有时候导致APP闪退 稍微研究会,总结了一下使用过程 ...
- java基础之字符串转日期
package com.iamzken.utils; import java.text.ParseException; import java.text.SimpleDateFormat; impor ...
- jQury(事件及其他方法)
一. jQuery 事件注册 单个事件注册 语法: element.事件(function(){}) $("div").click(function(){ 事件处理程序 }) 其他 ...
- 工作记录:TypeScript从入门到项目实战(项目篇)
Vue项目中使用 前面两篇介绍过TypeScript基础和较深入的东西,本章介绍如何在Vue项目中使用. 项目创建 创建项目直接使用Vue-cli创建 下面是步骤: 1.运行vuecli, 2.选择合 ...
- 记录--你还在傻傻的npm run serve吗?快来尝尝这个!
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 背景 大家在日常开发中应该经常会有需要切换不同环境地址的情况.当一个项目代码切换环境地址时,vue-cli没有能够感知文件的变化,所以代理 ...
- 神经网络——基于sklearn的参数介绍及应用
一.MLPClassifier&MLPRegressor参数和方法 参数说明(分类和回归参数一致): hidden_layer_sizes :例如hidden_layer_sizes=(50, ...
- 在Centos7上安装Redis6
一.背景 Redis是一个非常流行的NOSQL数据库,拥有的数据类型非常丰富,此处我们简单记录一下在Centos7上是如何安装Redis6的.Redis的安装是推荐使用源码进行安装的. 二.安装步骤 ...
- AI+软件工程:10倍提效!用ChatGPT编写系统功能文档
系统功能文档是一种描述软件系统功能和操作方式的文档.它让开发团队.测试人员.项目管理者.客户和最终用户对系统行为有清晰.全面的了解. 通过ChatGPT,我们能让编写系统功能文档的效率提升10倍以上. ...
- kingbaseES sql 优化技巧汇总
1.整体思路 针对业务系统的出现的慢sql 我们的优化步骤大概分为以下几步 1.识别高负载语句 2.收集性能相关的数据 3.确定性能问题产生的原因 4.实施优化手段 下面我们针对这几个步骤展开进行讲解 ...