算法题:整数除法
创始人
2024-03-01 21:48:42
0

一.题目描述以及来源

给定两个整数 a 和 b ,求它们的除法的商 a/b ,要求不得使用乘号 '*'、除号 '/' 以及求余符号 '%' 。

注意:

整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2
假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231−1]。本题中,如果除法结果溢出,则返回 231 − 1

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/xoh6Oh
 

例子:

输入:a = 15, b = 2
输出:7
解释:15/2 = truncate(7.5) = 7
输入:a = 7, b = -3
输出:-2
解释:7/-3 = truncate(-2.33333..) = -2
输入:a = 0, b = 1
输出:0
输入:a = 1, b = 1
输出:1

二.解题思路

a=15b=2k=0
15>=b(a>=b)a=13k=1
15-2>=bk=2
13-2>=b3
11-2>=b4
9-2>=b5
7-2>=b6
5-2>=b7
3-2end

因为不能用除法,所以只能使用减法去实现除法。

实现的代码如下:

public static void Divide(int a, int b){//int sign = 1;//if((a>0 && b<0)||(a<0 && b > 0))//{//    sign= -1;//}int sign = (a > 0) ^ (b > 0) ? -1 : 1;a=Math.Abs(a); b=Math.Abs(b);int res = 0;while(a>=b){a=a-b;res++;}if(sign==-1){res = -res;}System.Console.WriteLine(res);}

此外还需要考虑,除法的符号,以及边界问题

 //时间复杂度是O(n),public static int DivideRange(int a, int b){//32位最大值: 2^31-1=2147483647//32为最小值:-2^31=—2147483648//—2147483648/(-1)=2147483648>—2147483647 越界if ((a == (-2147483648)) && (b == (-1))){return 2147483647;}             int sign = (a > 0) ^ (b > 0) ? -1 : 1;//Math.Abs(—2147483648)=—2147483648  所以我们将正数转成负数去计算if (a > 0){a = -a;}if (b > 0){b = -b;}int res = 0;//-7 /-2  =3 ,都是负数除法 转成 数学,循环是<=   例如 -7<=-2 ,继续循环while (a <= b){a = a - b;res++;}if (sign == -1){res = -res;}return res;}

上面为解体的完整代码,需要注意的有

1.范围时,注意范围的边界(最小值/-1  会越界,最小值取正数 会保持原值)

2.将所有数转成负数去进行计算,因为最大值可以取相反数,最小值相反数越界

3.原本数字都变成正数的时候,判断是a>=b,作为循环的条件。转成负数计算的时候,循环的条件是a<=b

4.在c#中Integer.MIN_VALUE为


int max = int.MaxValue;
int min = int.MinValue;

三. 解题思路(2)

此思路看不懂的话可以去看看leetcode讲解视频:简单易懂Java/C++ /Python/js/go - 整数除法(剑指) - 整数除法 - 力扣(LeetCode)

 

public static int DivideVersion2(int a, int b){//32位最大值: 2^31-1=2147483647//32为最小值:-2^31=—2147483648//—2147483648/(-1)=2147483648>—2147483647 越界if ((a == (-2147483648)) && (b == (-1))){return 2147483647;}int sign = (a > 0) ^ (b > 0) ? -1 : 1;//Math.Abs(—2147483648)=—2147483648  所以我们将正数转成负数去计算if (a > 0){a = -a;}if (b > 0){b = -b;}int res = 0;//  22/7while (a <= b){int value = b;int k = 1;while (a < value + value){k = k + k;value = value + value;}res += k;a = a - value;}if (sign == -1){res = -res;}System.Console.WriteLine(res);return res;}

此方法会超时,而且会有越域的情况

四,解题思路(3)位运算

在三的解题思路之上,我们知道我们可以实行b*2去减去a一半的情况。将b*2转换成b<<2,b往左移一位。

 

public class Solution {public int Divide(int a, int b) {if ((a == int.MinValue) && (b == (-1))){return int.MaxValue;}int res = 0;if (b == int.MinValue) {return a == b? 1 : 0;}// 被除数先减去一个除数if (a == int.MinValue) {a -= -Math.Abs(b);res += 1;}int sign = (a > 0) ^ (b > 0) ? -1 : 1;a = Math.Abs(a); b = Math.Abs(b);for(int i = 31; i >= 0; i--){if ((a >> i) - b >= 0){   if (res > int.MaxValue - (1 << i)) {return int.MinValue;}            a=a-(b<

 上面for循环内实现了整个逻辑,需要注意的是i=0是表示-b本身,所以需要i>=0.

 以下是处理边界值的代码,测试之前没发现。

if (b == int.MinValue) {return a == b? 1 : 0;}// 被除数先减去一个除数if (a == int.MinValue) {a -= -Math.Abs(b);res += 1;}

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...