首页 > 其他分享 >剑指Offer II 001.整数除法

剑指Offer II 001.整数除法

时间:2022-12-13 01:22:52浏览次数:55  
标签:折半 elif Offer INT 31 II 001 abs ans

题目描述

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

注意:

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

解题分析

  1. 不使用 * 、%、/。
    a/b=c 可转化成 a=b*c,然后通过快速乘算法运算。快速加过程中要小心加结果溢出,所以当加得结果大于a时及时停止。
  2. 截去小数部分。
    运用二分查找,先取c=a,然后折半取值,直到 0<=a-b*c<b,找到合适的C。
  3. 数值范围。
    分情况讨论32位有符号数由补码表示,取值范围在[−2^31, 2^31−1],可能的取值分类如下:
    *溢出:a=−2^31,b=-1,此时 2^31−1;
    *若 b=INT_MIN,且 a<INT_MIN ,则 c=0;
    *若 b=INT_MIN,且 a=INT_MIN,则 c=1;
    *若 b=1,则 c=a;
    *若 b=-1,则 c=-a;
    *若 a-b * c>b,则c估值过小,向上折半取值;
    *若 a-b * c<0,则c估值过大,向下折半取值。
  4. 化简运算。
    直接取除数和被除数的负数进行运算,能兼顾所有数据且不会导致溢出。如果两数同符号,结果不变;如果两数符号相反,结果加上负号。

Python代码

分类讨论

#溢出
if a == INT_MIN and b == -1:
    c = INT_MAX

#除数绝对值大于或等于被除数绝对值
elif abs(b) > abs(a):
    c = 0
elif abs(b) == abs(a):
    if a != b:
        c = -1
    elif a == b:
        c = 1 
    
#被除数等于1或-1
elif b == 1:
    c = a
elif b == -1:
    c = -a

#其他情况下用二分查找
else:
    left = INT_MIN
    right = -1
    mid = 0
    c = 0
    while left <= right:
        mid = right + ((left - right) >> 1 )
        ans = quickMult (-abs(a), -abs(b), abs(mid)) 
        if ans == 1: # c过大,向右折半
            left = mid + 1
        elif abs(a) - abs(ans) >= abs(b): # c过小,向左折半
            right = mid - 1
        elif abs(a) - abs(ans) < abs(b): # c合适,输出
            if (a < 0 and b > 0) or (a > 0 and b < 0):
                c = mid
            else:
                c = -mid
            break

快速乘算法

def quickMult( a, b, c ):#小心溢出
    ans = 0
    while c:
        if b < a: # b已经超过a,结果过大向左折半
            return 1
        if c & 1:
            if a - ans > b :# b*c > a 结果过大向左折半
                return 1
            ans += b
        b += b
        c >>= 1
    return ans

标签:折半,elif,Offer,INT,31,II,001,abs,ans
From: https://www.cnblogs.com/tree123/p/16976061.html

相关文章

  • 脑筋急转弯-2498. 青蛙过河 II
    2498.青蛙过河IIDescriptionDifficulty:中等RelatedTopics:给你一个下标从0 开始的整数数组 stones ,数组中的元素 严格递增 ,表示一条河中石头的位置。一只......
  • [LeetCode]001-两数之和
    >>>传送门题目给定一个整数数组nums 和一个整数目标值target,请你在该数组中找出和为目标值target 的那 两个 整数,并返回它们的数组下标。你可以假设每种输入......
  • BZOJ4536 : 最大异或和II
    建立$n+m$个点的无向图,其中$n$个点表示输入的数列,$m$个点表示答案的$m$个二进制位。对于输入的两个数$a[i],a[j]$,若它们存在公共二进制位,则可以通过同时选某一公共位来对......
  • 【LeetCode】二分法--剑指 Offer 53 - I. 在排序数组中查找数字 I
    点击直达题目内容统计一个数字在排序数组中出现的次数。示例示例1:输入:nums=[5,7,7,8,8,10],target=8输出:2示例2:输入:nums=[5,7,7,8,8,10],target......
  • 190001 求平方根近似值已知任意一个正数
    点击查看代码<?phpheader('Content-Type:text/html;charset=utf-8');define('ROOT',$_SERVER['DOCUMENT_ROOT']);includeROOT.'/assets/php/head.php';$tit='......
  • python-miio 入门
    一、获取ip和tooken转载链接:https://github.com/PiotrMachowski/Xiaomi-cloud-tokens-extractor二、基础通信转载链接:https://github.com/rytilahti/python-miio/iss......
  • 剑指 Offer 56 - II. 数组中数字出现的次数 II(状态转移 位运算)
      ​​剑指Offer56-II.数组中数字出现的次数II​​难度中等38在一个数组 ​​nums​​ 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次......
  • 剑指offer面试题38. 字符串的排列(回溯)
    ​​面试题38.字符串的排列​​难度中等48输入一个字符串,打印出该字符串中字符的所有排列。 你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。 示例:输入:s=......
  • 剑指offer 数组中的逆序对(归并排序)
    ​​剑指Offer51.数组中的逆序对​​难度困难176在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的......
  • 剑指offer 数据流中的中位数(思维,堆)
    题目描述如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值......