每日一题「整数除法」
Posted 陈皮的JavaLib
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每日一题「整数除法」相关的知识,希望对你有一定的参考价值。
我是陈皮,一个在互联网 Coding 的 ITer,个人微信公众号「陈皮的JavaLib」关注第一时间阅读最新技术文章。
文章目录
题目
输入2个 int 型整数,将它们进行除法计算并返回商,要求不得使用乘号、除号及求余符号。当发生溢出时,返回最大的整数值。假设除数不为0。例如,输入15和2,输出15/2的结果,即7。
分析
限制了不可以使用除法,乘法,和求余运算,那么可以使用减法来实现除法。
例如15/2,不断地从15里减去2,当减去7个2之后余数是1,余数不能再减去2,所以15/2的商是7。使用一个循环即可实现这个过程。
不过,但当被除数很大但除数很小时,减法操作执行的次数会很多。例如,当被除数为 int 类型的最大值 2^31 - 1,除数为1时,减1操作次数为 2^31 - 1 次。当除数为2时,减2操作次数也要 2^30 次左右。这样会导致算法速度很慢。
所以我们需要优化,如果被除数大于除数时,判断被除数是否大于除数的2倍,如果是,再判断是否4倍,8倍…,直到最多2n倍。然后将被除数减去2n个除数,2n的值累加到总的减次数中,将剩余的被除数继续重复以上操作,直到剩余的被除数小于除数。因为每次将除数翻倍,所以时间复杂度是O(logn)。
因为被除数和除数都有可能是负数,为方便计算,需要先将它们都转为同符号的整数,计算出结果后,再进行对商调整符号。如果将负数都调整为正数,有可能会发生溢出,例如负数-231,但是正数最大值是231-1。所以我们选择将正数转为负数,对两个负数进行除法求商,最后再对商的符号进行调整。
实现
package com.chenpi;
/**
* @author 陈皮
* @version 1.0
* @description
* @date 2022/3/17
*/
public class ChenPi
public static void main(String[] args)
ChenPi inst = new ChenPi();
int dividend = -18;
int divisor = 3;
System.out.println(inst.divide(dividend, divisor));
public int divide(int dividend, int divisor)
// 这种情况会发生溢出
if (dividend == Integer.MIN_VALUE && divisor == -1)
return Integer.MAX_VALUE;
// 记录负号的个数
int negativeCount = 2;
// 被除数如果为正数转为负数
if (dividend > 0)
dividend = -dividend;
negativeCount--;
// 除数如果为正数转为负数
if (divisor > 0)
divisor = -divisor;
negativeCount--;
// 商
int result = 0;
// 被除数小于除数时(因为它们都是负数),重复
while (dividend <= divisor)
// 记录最大的|除数*2n|绝对值
int timesValue = divisor;
// 减去除数的次数
int times = 1;
// 最小值是-2^31,0xc0000000是-2^30,避免timesValue是-2^31时,timesValue + timesValue发生溢出
while (timesValue >= 0xc0000000 && dividend <= timesValue + timesValue)
times += times;
timesValue += timesValue;
result += times;
dividend -= timesValue;
// 商符号调整
return negativeCount == 1 ? -result : result;
输出结果
-6
本次分享到此结束啦~~
如果觉得文章对你有帮助,点赞、收藏、关注、评论,您的支持就是我创作最大的动力!
以上是关于每日一题「整数除法」的主要内容,如果未能解决你的问题,请参考以下文章