程序员面试金典面试题16。09。运算
题目难度: 中等
原题链接 [1]
今天继续更新程序员面试金典系列, 大家在公众号 算法精选 里回复 面试金典 就能看到该系列当前连载的所有文章了, 记得关注哦~ 题目描述
请实现整数数字的乘法、减法和除法运算,运算结果均为整数数字,程序中只允许使用加法运算符和逻辑运算符,允许程序中出现正负常数,不允许使用位运算。
你的实现应该支持如下操作: Operations() 构造函数 minus(a, b) 减法,返回 a - b multiply(a, b) 乘法,返回 a * b pide(a, b) 除法,返回 a / b 示例:Operations operations = new Operations(); operations.minus(1, 2); //返回-1 operations.multiply(3, 4); //返回 12 operations.pide(5, -2); //返回-2 提示:你可以假设函数输入一定是有效的,例如不会出现除法分母为 0 的情况 单个用例的函数调用次数不会超过 1000 次 题目思考可以从哪个运算入手? 是否可以利用已经实现的操作? 解决方案思路这道题目乍一看无从下手, 如何做到只使用加法和逻辑运算符来实现减/乘/除呢? 首先来看减法, a-b 相当于 a+(-b), 如果我们能够实现取反操作, 则直接就能实现减法 要实现取反, 我们可以利用数字的二进制性质, 维护每一个 2 的幂和 -2 的幂, 然后如果当前数字的某一个二进制位为 1 的话, 直接加上与之对应的相反数即可, 具体过程可以参考下面代码 然后再说乘法, 我们可以利用因数分解来实现, 例如 123*15=123*(8+4+2+1) , 我们可以维护当前的因子和乘积, 每次循环到因子最接近当前被乘数为止, 然后累加乘积并将被乘数减去因子, 继续循环直到被乘数变为 0最后再看除法, 同样可以利用因数分解来实现, 例如 123/10=12=8+4 , 维护当前的商和乘积, 每次循环到乘积最接近当前被除数为止, 然后累加商并将被除数减去乘积, 继续循环直到被除数小于除数另外乘除法也要处理操作数的符号问题, 可以将操作数统一转成正数方便处理, 这里利用上面定义好的取反操作即可 下面代码就对应了上面的整个过程, 且每一步有详细的注释, 方便大家理解 复杂度时间复杂度 O(logN) : 减/乘/除都需要遍历 32 位空间复杂度 O(logN) : 需要存储 2*32 个 2 的幂代码class Operations: def __init__(self): # ps存储[1,2,4,...], 即2的幂 # ns存储[-1,-2,-4,...], 即-2的幂 # 利用这两个数组来实现取反操作 self.ps = [] self.ns = [] self.n = 32 p, n = 1, -1 for i in range(self.n): self.ps.append(p) self.ns.append(n) if i < 31: p = self.lShift(p) n = self.lShift(n) def neg(self, x: int) -> int: res = 0 if x > 0: # x是正数, 从大到小遍历2的幂, 如果当前数字大于等于该幂时, 将该数字和最终结果都加上对应的相反数 # 例如x=15=8+4+2+1, 其相反数-15=(-8)+(-4)+(-2)+(-1) for i in range(self.n)[::-1]: if x >= self.ps[i]: res += self.ns[i] x += self.ns[i] if x == 0: # x已经达到0, 没有必要继续遍历, 直接break break elif x < 0: # 类似上面的过程, 只是改变判断符号 for i in range(self.n)[::-1]: if x <= self.ns[i]: res += self.ps[i] x += self.ps[i] if x == 0: break return res def lShift(self, x: int) -> int: # 左移操作等价于x+x return x + x def minus(self, a: int, b: int) -> int: # a-b即为a+(-b), 直接利用上面定义的取反操作即可 return a + self.neg(b) def multiply(self, a: int, b: int) -> int: if a == 0 or b == 0: # 乘数为0, 积也为0 return 0 if b < 0: # 将b取反转成正数, 方便处理, 注意最终结果也要取反 return self.neg(self.multiply(a, self.neg(b))) # 因子分解实现乘法 # 例如multiply(123,15), 123*15=123*(8+4+2+1) # 外层循环4次, 对应的cur和t分别是(123*8, 8), (123*4, 4), (123*2, 2), (123*1, 1), 累加cur即为最终乘积 res = 0 # 注意循环条件是b!=0, 因为最终因子一定能分解成多个2的幂的和, b一定能变成0 while b: # cur表示当前部分的乘积 cur = a # t表示当前不超过b的因子 t = 1 while self.lShift(t) <= b: cur = self.lShift(cur) t = self.lShift(t) # 更新最终乘积和b res += cur b = self.minus(b, t) return res def pide(self, a: int, b: int) -> int: if a == 0: # 被除数为0, 商也为0 return 0 # 将除数和被除数都转成正数, 并加上对应符号, 方便处理 pos = True if a < 0: a = self.neg(a) pos = not pos if b < 0: b = self.neg(b) pos = not pos # 因子分解实现除法 # 例如pide(123,10), 123/10=12=8+4 # 外层循环2次, 对应的cur和t分别是(8, 10*8), (4, 10*4), 累加cur即为最终的商 res = 0 # 注意循环条件是a>=b, 因为a= b: # cur表示当前部分的商 cur = 1 # t表示当前不超过a的乘积 t = b while self.lShift(t) <= a: cur = self.lShift(cur) t = self.lShift(t) # 更新最终商和a res += cur a = self.minus(a, t) if not pos: res = self.neg(res) return res 参考资料
[1]
原题链接: https://leetcode-cn.com/problems/operations-lcci/
2019,翼联祝大家元宵节快乐!正月十五闹元宵年年花相似,岁岁人不同。又是一年元宵佳节至,刚刚过去的这个春节,还在唇齿留香,年味还未散尽。年年花相似,岁岁人不同。又是一年元宵佳节至,刚刚过去的这个春节,还在唇齿留
2018在翼联EDUP,圣诞节我们一起过!圣诞气氛越来越浓啦。每天下班路上都可以听着SingleDog,SingleDog,SingleAllTheDay,只能看依偎的小情侣呈指数级增长。你是否期待成为那个幸运的人,在喧嚣
流浪地球太远,流浪翼联很近现在是北京时间2019年2月12日17时53分,糯米网电影票房实时更新流浪地球票房破25。08亿。影片对于中国科幻电影发展的里程碑作用毋庸置疑,场面宏大制作精良,确实值得一看。故事
来看看小吃店老板娘都赞不绝口的一款神器到底是什么?随着4G路由器的火爆,身边越来越多人在用4G路由器,不仅个人在出租房使用还有一些小吃店商家也陆续在店铺使用这款4G路由器!但是,还是有很多朋友们不知道到底如何使用?一脸懵逼今天小编
不可思议,原来你是这样的4G路由!现如今,无论在咖啡店火车站,还是地铁上,大家用手机玩游戏的场景随处可见。令人深思的是,在免费WiFi遍地的情况下,大家玩游戏用的却是4G网络。而背后的原因竟是WiFi不顺畅,满足不
招兵买马,小伙伴们,翼联EDUP招人啦!当初你背井离乡来到深圳我想你一定是为了某个梦想深夜里还在加班工作就为了完成自己当初定下的目标然而你绝不是仅仅为了一份糊口的工作才去做但是这背后的辛酸苦楚,却只有我们自己才懂。但,你
年年回老家担心没网,今年让你不再愁!年复一年,又到了每年回家过年的时候了,有人欢喜有人愁!开心的是能和家里亲人团聚,愁的是如果在偏远农村山区,过年回家家里没有宽带,想和朋友联系发个语音或者上传个视频都困难,更不用说有
谢大脚车祸中一死三伤,为什么还要赔偿骆驼主人费用?谢大脚演员于月仙遭遇车祸,不幸去世,让人痛惜不已。不过分析一个事情,要一分为二地看。谢大脚剧组方虽因车祸发生了伤亡,是否还要赔偿遭受损失的另一方,也就是被撞死骆驼的主人呢?阿拉善骆
一文读懂WiFi6这才是千兆路由和无线网卡的正确选择WiFi6是什么?WiFi6是由无线网络标准的WiFi联盟提出的命名规则,将802。11ax更名为WiFi6,于2019年发布,并将前两代技术802。11n和802。11ac分别更
在家上网台式机不想拉网线怎么办?不知道平时在家上网您是否遇到过这样的问题?宽带在客厅,电脑在书房,拉线又太麻烦,头疼啊!如果您觉得实在无法忍受,那就考虑一下选择我们吧!翼联EDUP最新推出的穿墙版无线网卡EPMS
2019年,翼联行动,火爆来袭!过年回家的这段时间七大姑八大姨肯定轰炸你了吧小哥哥在哪儿工作啊?小姐姐工作怎么样啊?薪资多少呀?领导人好吗?同事又怎样呀?可怕吗?不可怕因为我在翼联EDUP工作呀,全深圳都有名的电