【LeetCode】数值运算(除法、乘方)
C/C++数字范围(32位系统)
bool: ~ // 1 字节
char // 1 字节
short: - ~ // 2 字节
int: - ~ // 4 字节
unsigned: ~ // 4 字节
size_t: ~ // 4 字节
long: - ~ // 4 字节,Linux64位下的long占 8 字节!!!
unsigned long: ~ // 4 字节
long long: - ~ // 8 字节
unsigned long long: ~ // 8 字节
__int64: - ~ // 8 字节
unsigned __int64: ~ // 8 字节
float: 1.17549- ~ 3.40282e+038 // 4 字节
double: 2.22507e-308 ~ 1.79769e+308 // 8 字节
long double: 3.3621e-4932 ~ 1.18973e+4932 // 12 字节
1. 整数除法
实现整数除法,不使用 * 、/ 、% 三个运算符。若结果越界,返回 INT_MAX。
原理:
假设计算 15 除以 3,15 是 dividend 被除数,3 是 divisor 除数。
“除法”需要知道 dividend 能够减去 divisor 多少次而不使 dividend 为负。
开始计算叭~将结果记录在 result 中(初始化为0)。
首先 15 - 3 = 12 > 0;尝试减去更大的数,把 3 左移一位 (0011)2 -> (0110)2 得到 6,15 - 6 > 0;再左移一位得到 12,15 - 12 > 0;继续左移一位得到24,15 - 24 < 0。这样我们知道 dividend (15) 最多能减 12。12 是由 divisor (3) 左移 2 次得到,左移 2 次相等于 × 4,4 即为 (0001)2 左移 2 次得到,因此将 4 加到 result 中。
接下来 dividend 15 - 12 后剩余 3,重复上述计算,将 1 加到 result 中得到最终答案 5。
被除数和除数若含有负数,则统一化为正数按上述算法计算后,再判断 result 符号即可。
C++实现:
int divide(int dividend, int divisor) {
// 整数除法,因此只有当 dividend == -231,divisor == -1 时结果才会越界
if (!divisor || (dividend == INT_MIN && divisor == -))
return INT_MAX;
/* !使用 异或 操作符判断符号值得学习! */
int sign = ((dividend < ) ^ (divisor < )) ? - : ;
// dividend == -231时,取绝对值后仍赋值给 int 则会越界,因此存储在 long long
long long dvd = labs(dividend);
long long dvs = labs(divisor);
int res = ;
while (dvd >= dvs) {
long long temp = dvs, multiple = ;
while (dvd >= (temp << )) {
temp <<= ;
multiple <<= ;
}
dvd -= temp;
res += multiple;
}
return sign == ? res : -res;
}
2. 乘方
实现 Pow(x, n)。
若用类似于求 n 的阶乘的递归方法计算,时间复杂度为 O(n)。
但考虑到 n 个 x 相乘式子的对称关系,可以采用二分法,xn = xn/2 * xn/2 * xn%2,时间复杂度为 O(logn)。
C++实现:
double myPow(double x, int n) {
if (!n)
return ;
if (n < ) {
n = -n;
x = / x;
}
return (n % == ) ? myPow(x * x, n / ) : x * myPow(x * x, n / );
}
但这段代码并没有做边界条件判断,n 取值 INT_MIN 时,-n 并不是 INT_MAX

需要在 n < 0 的条件下增加判断
if (n == INT_MIN)
return / (x * myPow(x, INT_MAX));
或者改为
if (n < ) {
return / (x * myPow(x, -(n + )));
}
最后可以用位运算加快执行速度
double myPow(double x, int n) {
if (!n)
return ;
if (n < ) {
return / (x * myPow(x, ~n));
}
return ((n & ) == ) ? myPow(x * x, n >> ) : x * myPow(x * x, n >> );
}
用 ~n 代替 -(n + 1)。
e.g. n = 15,求 ~n。
n的源码 = 00000000 00000000 00000000 00001111
正数的补码是自身(计算机以补码存储数据)
n的补码 = 00000000 00000000 00000000 00001111
按位取反(包括符号位)
~n的补码 = 11111111 11111111 11111111 11110000
负数的补码是源码取反加1,源码也是补码取反加1(符号位不变)
~n的源码 = 10000000 00000000 00000000 00010000
求得 ~n 为 -16。同理 n = -15 时,求得 ~n = 14。
if ((n & 1) == 0) 判断奇偶效率更高,虽然编译器都会将 n % 2 优化为位运算。
但值得注意的是,& 作为“按位与”而不是“取地址符”时,其优先级低于 == 和 !=,因此如果不写括号的话 (n & 1 == 0) 为永 false 的。
编写更加易读的代码比起过多考虑细枝末节的效率问题更加重要!若想高效,建议改进算法,而不是改进写法!
递归虽然很好理解,但会占用递归栈的空间,因此用迭代的方法更加高效。
考虑 n 的二进制表示,例如 n = (1000 1011)2,那么xn = x1+2+8+128 = x1 * x2 * x8 * x128。
因此可以循环 n 的每一位,如果该位置是 1,就把 xi 乘到结果中去,时间复杂度为 O(logn)。
任何数与 1 相与结果不是 0 就是 1,一般用 n & 1 判断 n 的奇偶,这里则是不断把 n 右移一位,判断 n 的最后一位是不是 1,如果是 1,就把 xi 乘到结果中去。
double myPow(double x, int n) {
if (!n)
return ;
if (n < ) {
return / (x * myPow(x, ~n));
}
double result = ;
for(; n > ; x *= x, n >>= ) {
if (n & > )
result *= x;
}
return result;
}
3.
【LeetCode】数值运算(除法、乘方)的更多相关文章
- 数值运算内建函数(core python programming 2nd edition 5.6.2)
数值运算内建函数 函数 功能 abs(num) 返回 num 的绝对值 coerce(num1, num2) 将num1和num2转换为同一类型,然后以一个元组的形式返回. divmod(num1, ...
- Swift数值运算
Swift 让全部数值类型都支持了主要的四则运算: 加法(+) 减法(-) 乘法(*) 除法(/) 1 + 2 // 等于 3 5 - 3 // 等于 2 2 * 3 // 等于 6 10.0 / 2 ...
- 1.9 Python基础知识 - 数值运算
一.数值运算 在Python中有丰富的算术运算,这使得Python在科学计算领域有着很高的地位,Python可以提供包括四则运算在内的各种算术运算. 算术运算符 运算符 含义 说明 优先级 实例 ...
- Shell基础(二):Shell中的数值运算、条件测试操作、使用if选择结构
一.Shell中的数值运算 目标: 本案例要求熟悉Linux Shell环境的特点,主要练习以下操作: 1> 使用expr.$[ ].let等整数运算工具:定义变量X=1234,然后计算X与78 ...
- shell简单用法笔记(shell中数值运算)二
shell中变量值,如果不手动指定类型,默认都是字符串类型: 例如: a= b= c=$a+#b echo $c 结果会输出:123+456 shell中,如果要进行数值运算,可以通过一下方法: 方法 ...
- 在shell script中进行数值运算的两种方法
方法1:使用"$((计算式))"的方式进行数值运算,不需要使用declare命令显示声明数值型变量来存储计算结果: 方法2:使用declare命令配合"-i"选 ...
- leetcode - 位运算题目汇总(下)
接上文leetcode - 位运算题目汇总(上),继续来切leetcode中Bit Manipulation下的题目. Bitwise AND of Numbers Range 给出一个范围,[m, ...
- shell之数值运算
Shell中声明变量默认是字符串, 要参与数值运算,可使用下面方式,简单,表示以数值方式.
- linux中的数值运算
一.declare 作用:声明变量类型,bash默认变量为字符串类型的,并且字符串在拼接时直接拼接,不需要加号 使用方法: 二.数值运算 加法运算 a= b= c=$(($a+$b)) echo $c
- shell脚本基础 数值运算 判断 及if语句
数值运算 整数运算[三种,随便掌握一种即可]expr 数字 运算符 数字 [root@ceshiji ~]# expr 1 + 1(运算符号都是+ - * / 注:*需要\*.%是取余,余数只有0 1 ...
随机推荐
- pyqt笔记2 布局管理
https://zhuanlan.zhihu.com/p/28559136 绝对布局 相关方法setGeometry().move() 箱式布局 QHBoxLayout和QVBoxLayout是基本的 ...
- js运算符的一些特殊应用
作者: 小文 来源: http://www.cnblogs.com/daysme/ 时间: 2017/3/2 17:21:03 本文集合了了js运算符的一些特殊应用. js位运行符的运用. js运算符 ...
- python学习 day013打卡 内置函数
本节主要内容: 内置函数: 内置函数就是python给你提供的.拿来直接用的函数,比如print,input等等.截止到python版本3.6.2 python一共提供了68个内置函数.他们就是pyt ...
- [从零开始搭网站五]http网站Tomcat配置web.xml和server.xml
点击下面连接查看从零开始搭网站全系列 从零开始搭网站 上一章我们在CentOS下搭建了Tomcat,但是还是没有跑起来...那么这一章就把最后的配置给大家放上去. 有两种方式:一种是用 rm -f 给 ...
- 项目Alpha冲刺--5/10
项目Alpha冲刺--5/10 1.团队信息 团队名称:基于云的胜利冲锋队 成员信息 队员学号 队员姓名 个人博客地址 备注 221500201 孙文慈 https://www.cnblogs.com ...
- Easyui使用心得(1)--DateGrid表格
最近一直在用easyui这个控件,有一点心得,在这里和大家分享一下,也是对自己工作的一个小小的总结,希望可以形成一个完整的Easyui的笔记体系,可以方便更多的人 因为自己也是在摸索中前进,难免有遗漏 ...
- 要使用myConfig.properties配置文件作为实体类的映射文件的话,格式要用=,最关键的要和实例类中通过反射获取值的KEY要一样,不样会反射取不到值
ABC=https://fsdfsdf.iy.comABCId=L2345345ZhP345ABCKey=sfdf4234f234dhE6Ut0aABCName=Gassd010 上面是myConfi ...
- stop 用法
1. stop 文档 $(selector).stop(stopAll,goToEnd) stopAll 可选.规定是否停止被选元素的所有加入队列的动画.goToEnd 可选.规定是否允许完成当前的动 ...
- 学习笔记42—Win7下安装Linux双系统
1.下载Linux镜像:http://mirrors.163.com/ubuntu-releases/18.04.1/ 方法一: 1.用软通牒软件将Linux的镜像写入空的优盘中, 具体如下: 1) ...
- vscode下ts-node传入cli参数
ts-node写ts,启动时习惯在package.json里写 "scripts": { "build-ts": "tsc", " ...