赞
踩
题目描述
给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。
返回被除数 dividend 除以除数 divisor 得到的商。
整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2
来源:力扣(LeetCode)
题目分析
整除计算,不允许使用乘除和mod运算,因此考虑采用加减运算,比较大小来进行除法的计算。除数和被除数的符号共有四种组合(++, +-, -+, --),因此需要考虑分情况讨论或统一符号运算。
* 累加来模拟除法,如何提高效率
第一思路:递归法
采用最简单的思路,分四种情况分别逐个累加或累减操作。结果超出时间限制,单倍累加效率过低
- while(cnt + cnt > dividend){
-
- mul += 1;
-
- cnt += divisor;
-
- }
改进思路:
单倍累加过于低效,采用2的幂次方倍来逐次累加,加快搜索速度。
- static long _div(long dividend, long divisor){
- if (dividend > divisor) return 0;
- long mul = 1, cnt = divisor;
- // 采用 2的幂次方来扩大步幅
- while(cnt + cnt > dividend){
- mul += mul;
- cnt += cnt;
- }
- return mul + _div(dividend - cnt, divisor);
- }
-
- int divide(int dividend, int divisor) {
- if (dividend == 0) return 0;
- bool sign = (dividend > 0) ^ (divisor > 0); // 异或操作,判断符号
- // 除数被除数都转为负数进行计算,正数最大值翻转时会出现溢出的情况
- if (dividend > 0) dividend = -dividend;
- if (divisor > 0) divisor = -divisor;
- // 此处采用递归来计算,可以考虑改为动态规划
- // 考虑到累加结果可能溢出,申请long来表示
- long res = _div(dividend, divisor);
- res = (sign)? -res : res;
- return res>INT_MAX?INT_MAX:res;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。