LeetCode :: Pow(x, n)
来源:互联网 发布:企业数据防泄密体系 编辑:程序博客网 时间:2024/06/05 06:18
函数的原型是这样的:double pow(double x, int n) ;
一、这里最容易想到的,肯定是时间复杂度为O(N), 利用一个递归,我试了一下,果然和想的一样 TL。
二、把pow分解为 pow(x, n / 2) ,T(N) = T(N / 2) + O (1),这里的时间复杂度利用master method,显而易见是O(logN)
#include <iostream>using namespace std;double pow(double x, int n) { double result = 1, tmp; if (n == 0) return 1; if (n > 0){ tmp = pow(x, n / 2); if (n % 2){ result = tmp * tmp * x; } else{ result = tmp * tmp; } } else{ tmp = pow(x, -n); result = 1 / tmp; } return result; }int main(){ double x; int n; cin >> x >> n; cout << pow (x , n);}
这个代码是有错误的代码,SUMBIT的时候,提示了Runtime error,通不过的case是 1.00000, -2147483648
这里有个值得注意的地方,这个-2147483648是32位带符号整型的最小值,这里展开说一下。
首先更正一个经常性的教科书错误,补码是什么?怎么去得到?我以前的第一反应是原码取反加1,我们考虑一下-128,假设是一个8位存放,那么它的原码是什么?你根本找不到,因为溢出了。其实,机器里面,根本就是一个完全的补码存放,补码计算的机制,这个所谓的原码只是方便我们记忆而已。
好,然后考虑这个边界问题。
问题1:int -2147483648 ;编译后的值正确吗?
上面说的转换程序,这个编译的步骤为: 计算2*10^9 + 2*10^8+ …… +4*10+8 ,因为int只能表示到 2147483647 (0x7fff ffff),再加1的话就溢出了,得到了:0×8000 0000 ,(就是 -2147483648) ,然后再把这个结果与 -1 就是 0xffff ffff 相乘,得到的结果也溢出了,为:0×8000 0000 ,但是这恰好是 – 2147483648的补码,所以,虽然编译中虽然出现了两次溢出,但得到的结果是正确的。
问题2:int x = – 2147483648; 那么 –x 是 2147483648吗?
因为 – 2147483648 (0×8000 0000)与-1 (0xfff ffff)相乘结果为:0×8000 0000 就是– 2147483648 ,所以 –x 的结果还是 – 2147483648 而不是2147483648 。 所以,凡是结果可能超越表示范围的时候,一定要慎重,因为结果可能是你意料之外的
PS: 上面的两个问题我是从http://moper.me/summary-points-of-four-code-conversion-2.html里面摘抄的,如果原作者看到,请原谅我冒昧,没经过同意。
这里就是出现了Runtime error的根本原因了,n = -– 2147483648, -n 也是 这个值,根本不会改变,然后我之前的代码那样的话,就一直陷入了那个n < 0的怪圈里面的了,然后就没有然后了,Runtime error。改之。
double pow(double x, int n) { double result = 1, tmp; if (n == 0) return 1; tmp = pow(x, abs(n / 2)); //这里用abs把负数取正,由于除以2之后,就不会在边界了。 if (n > 0){ if (n % 2){ result = tmp * tmp * x; } else{ result = tmp * tmp; } } else{ if (n & 1) return 1.0 / (tmp * tmp * x); else return 1.0 / (tmp * tmp); } return result; }
三、这里再介绍一个很有趣的方法也是logN的时间复杂度,但是它用到了一个移位的思想,下面是LeetCode网站上外国小伙在discuss中给出的思路。
Consider the binary representation of n. For example, if it is "10001011", then x^n = x^(1+2+8+128) = x^1 * x^2 * x^8 * x^128. Thus, we don't want to loop n times to calculate x^n. To speed up, we loop through each bit, if the i-th bit is 1, then we add x^(1 << i) to the result. Since (1 << i) is a power of 2, x^(1<<(i+1)) = square(x^(1<<i)). The loop executes for a maximum of log(n) times.
然后写了一下代码,这里利用了不同的对于边界值的处理方法。随便提一下,想要用到INT_MAX之类的定义好的常量应该包含头文件 climts 。
class Solution {public: double pow(double x, int n) { // Start typing your C/C++ solution below // DO NOT write int main() function if(n<0){if(n==INT_MIN)return 1.0 / (pow(x,INT_MAX)*x);elsereturn 1.0 / pow(x,-n);} if(n==0) return 1.0;double ans = 1.0 ;for(;n>0; x *= x, n>>=1){if(n&1>0)ans *= x;}return ans; }};
第一篇完了,废话有点多,如果有大神看了,感觉我哪里说的有问题,还希望大神们指出。
- LeetCode: Pow(x, n)
- LeetCode Pow(x,n)
- [Leetcode] Pow(x, n)
- LeetCode: Pow(x, n)
- Leetcode: Pow(x,n)
- [LeetCode] Pow(x, n)
- [Leetcode] Pow(x,n)
- 【leetcode】Pow(x, n)
- [LeetCode]Pow(x, n)
- [leetcode]Pow(x, n)
- LeetCode-Pow(x, n)
- LeetCode - Pow(x, n)
- LeetCode | Pow(x, n)
- Pow(x, n) -leetcode
- 【leetcode】Pow(x, n)
- 【Leetcode】Pow(x, n)
- LeetCode Pow(x, n)
- Leetcode: Pow(x, n)
- 安卓文件浏览器
- gradle是什么,新建工程停留在building gradle project info,gradle最新版本下载
- QTcpSocket 发送数据的几种方法
- kinect开发笔记1:openNI的配置
- 相关开发ios所需的小知识
- LeetCode :: Pow(x, n)
- Ant打包
- Camera.ScreenToWorldPoint
- 自己写的一个伪ajax图片上传实现代码
- Raphel image drag 拖动
- Android中共享全局变量
- Struts2入门二-参数和类型转换
- 让组件悬浮所有页面之上
- JAVA调用小票打印机