实现函数 double Power(double base, int exponent),求base的exponent次方。
注意:
1.保证base和exponent不同时为0。
2.不得使用库函数,同时不需要考虑大数问题
3.有特殊判题,不用考虑小数点后面0的位数。
数据范围:
,
,保证最终结果一定满足 
进阶:空间复杂度
,时间复杂度 %5C)
进阶:空间复杂度
2.00000,3
8.00000
2.10000,3
9.26100
2.00000,-2
0.25000
2的-2次方等于1/4=0.25
# -*- coding:utf-8 -*- class Solution: def Power(self, base, exponent): result = 1 if base == 0: return 0 if exponent == 0: return 1 if exponent < 0: for i in range(-exponent): result = result * base return 1/result for i in range(exponent): result = result * base return result上面的很简单,没有使用快速幂算法,下面使用一下快速幂算法,快速幂算法参考下面的博客
def fast_power(self, base, exponent): if base == 0: return 0 if exponent == 0: return 1 e = abs(exponent) tmp = base res = 1 while(e > 0): #如果最后一位为1,那么给res乘上这一位的结果 if (e & 1 == 1): res =res * tmp e = e >> 1 tmp = tmp * tmp return res if exponent > 0 else 1/res
java 实现
传统公式求解时间复杂度O(n)
public class Solution {
public double Power(double base, int exponent) {
double result=1;
for(int i=0;i<Math.abs(exponent);i++){
result*=base;
}
if(exponent<0){
result=1/result;
}
return result;
}
}
递归:n为偶数,a^n=a^n/2*a^n/2;n为奇数,a^n=(a^(n-1)/2)*(a^(n-1/2))*a
时间复杂度O(logn) public class Solution {
public double Power(double base, int exponent) {
int n=Math.abs(exponent);
if(n==0)
return 1;
if(n==1)
return base;
double result=Power(base,n>>1);
result*=result;
if((n&1)==1)
result*=base;
if(exponent<0)
result=1/result;
return result;
}
}
结合各位道友的意见,二刷如下
public class Solution {
public double Power(double base, int exponent) {
if(exponent==0 && base != 0)
return 1;
if(exponent==1)
return base;
if(base == 0 && exponent <= 0){
throw new RuntimeException();
}
if(base ==0 && exponent>0){
return 0;
}
int n= exponent;
if(exponent<0){
n = -exponent;
}
double result=Power(base,n>>1);
result*=result;
if((n&1)==1)
result*=base;
if(exponent<0)
result=1/result;
return result;
}
}
package javaTest;
public class JavaTest {
public static void main(String[] args) {
System.out.println(power(3, 3));
System.out.println(powerAnother(3, 3));
}
// 使用递归
public static double power(double base, int exponent) {
int n = Math.abs(exponent);
double result = 0.0;
if (n == 0)
return 1.0;
if (n == 1)
return base;
result = power(base, n >> 1);
result *= result;
if ((n & 1) == 1) // 如果指数n为奇数,则要再乘一次底数base
result *= base;
if (exponent < 0) // 如果指数为负数,则应该求result的倒数
result = 1 / result;
return result;
}
// 使用累乘
public static double powerAnother(double base, int exponent) {
double result = 1.0;
for (int i = 0; i < Math.abs(exponent); i++) {
result *= base;
}
if (exponent >= 0)
return result;
else
return 1 / result;
}
}
/*剑指书中细节:
*1.当底数为0且指数<0时
*会出现对0求倒数的情况,需进行错误处理,设置一个全局变量;
*2.判断底数是否等于0
*由于base为double型,不能直接用==判断
*3.优化求幂函数
*当n为偶数,a^n =(a^n/2)*(a^n/2)
*当n为奇数,a^n = a^[(n-1)/2] * a^[(n-1)/2] * a
*时间复杂度O(logn)
*/
public class Solution {
boolean invalidInput=false;
public double Power(double base, int exponent) {
if(equal(base,0.0)&&exponent<0){
invalidInput=true;
return 0.0;
}
int absexponent=exponent;
if(exponent<0)
absexponent=-exponent;
double res=getPower(base,absexponent);
if(exponent<0)
res=1.0/res;
return res;
}
boolean equal(double num1,double num2){
if(num1-num2>-0.000001&&num1-num2<0.000001)
return true;
else
return false;
}
double getPower(double b,int e){
if(e==0)
return 1.0;
if(e==1)
return b;
double result=getPower(b,e>>1);
result*=result;
if((e&1)==1)
result*=b;
return result;
}
} // 1.快速幂
public double Power(double base, int exponent) {
if (exponent == 0) {
return 1.0;
}
if (base - 0.0 == 0.00001 || base - 0.0 == -0.00001) {
if (exponent < 0) {
throw new RuntimeException("除0异常");
}else{
return 0.0;
}
}
int e = exponent > 0 ? exponent: -exponent;
double res = 1;
while (e != 0) {
res = (e & 1) != 0 ? res * base : res;
base *= base;
e = e >> 1;
}
return exponent > 0 ? res : 1/res;
}
// 2.递归
public double Power(double base, int exponent) {
if (exponent == 0) {
return 1.0;
}
if (base - 0.0 == 0.00001 || base - 0.0 == -0.00001) {
if (exponent < 0) {
throw new RuntimeException("除0异常");
}else{
return 0.0;
}
}
return exponent > 0 ? getPower(base, exponent) : 1/getPower(base, -exponent);
}
public static double getPower(double base, int e) {
if (e == 1) {
return base;
}
double halfPower = getPower(base, e >> 1);
return (e & 1) != 0 ? base * halfPower * halfPower : halfPower * halfPower;
}
class Solution {
public:
double Power(double base, int exponent) {
if(exponent == 0) return 1;
if(base == 0) return 0;
if(exponent == 1)
return base;
else if(exponent == -1)
return 1/base;
return Power(base,exponent/2) * Power(base,exponent/2) * Power(base,exponent%2);
}
};
exponent == 0 而 base 也 == 0 时竟然返回1,醉了JavaScript
方法一:调用系统函数
function Power(base, exponent) {
return Math.pow(base, exponent);
}方法二:暴力,速度慢;
function Power(base, exponent) {
var result = 1;
if (base == 0 && exponent < 0) {
throw new Error('输入错误');
}
for (var i = 0; i < Math.abs(exponent); i++) {
result *= base;
}
return exponent > 0 ? result : 1 / result;
}方法三:简单快速幂
思路:https://blog.csdn.net/hkdgjqr/article/details/5381028
function Power(base, exponent) {
var result = 1;
if (base == 0 && exponent < 0) {
throw new Error('输入错误');
}
var exp = Math.abs(exponent);
while (exp != 0) {
if ((exp & 1) == 1) {
result *= base;
}
base *= base; // 翻倍
exp >>= 1; // 右移
}
return exponent > 0 ? result : 1 / result;
}
用递归来处理很简单,主要注意的是分为两种情况来讨论,一种是指数exponent>=0的情况,一种是exponent<0的情况,后者只需要简单的处理下,让其变为倒数就可以了,代码如下:
class Solution{
public double Power(double base, int exponent) {
double res=0;
if (exponent>=0)
res=way(base,exponent);
else {
res=way(base,-exponent);
res=1/res;
}
return res;
}
private double way(double base,int n){
if (n==0)
return 1;
else
return base*way(base,n-1);
}
}
public class Solution {
public double Power(double base, int exponent) {
// return Math.pow(base,exponent);
double result=0.0;
if(base==0&&exponent<0){
return 0.0;
}
if(exponent>=0){
result = zhengshu(base,exponent);
}else{
result = 1.0/zhengshu(base,-exponent);
}
return result;
}
public static double zhengshu(double base, int exponent){
if(exponent==0){
return 1;
}
if(exponent==1){
return base;
}
double r=zhengshu(base,exponent>>1);
r*=r;
if((exponent&1)==1){
r*=base;
}
return r;
}
}
class Solution {
public:
//主要考察点:
//1指数为负责的情况;
//2递归实现快速乘方;
double Power(double base, int exponent)
{
if(abs(base) < 0.00000000001)//base为0的情况考虑
return 0;
bool neg = false;
if(exponent < 0)
{
exponent = -exponent;
neg = true;
}
double ret = Power_Help(base, exponent);
if(neg)
ret = 1.0 / ret;
return ret;
}
double Power_Help(double base, unsigned exponent)
{
if(exponent == 0)
return 1;
if(exponent == 1)
return base;
double ret = Power_Help(base, exponent >> 1);
ret = ret * ret;
//if(exponent & 1 == 1) 判断奇偶数更高效
if(exponent % 2 == 1)//容易遗漏:指数为奇数,少乘一次base,补上
ret = ret * base;
return ret;
}
};
/** * 1.全面考察指数的正负、底数是否为零等情况。 * 2.写出指数的二进制表达,例如13表达为二进制1101。 * 3.举例:10^1101 = 10^0001*10^0100*10^1000。 * 4.通过&1和>>1来逐位读取1101,为1时将该位代表的乘数累乘到最终结果。 */ public double Power(double base, int n) { double res = 1,curr = base; int exponent; if(n>0){ exponent = n; }else if(n<0){ if(base==0) throw new RuntimeException("分母不能为0"); exponent = -n; }else{// n==0 return 1;// 0的0次方 } while(exponent!=0){ if((exponent&1)==1) res*=curr; curr*=curr;// 翻倍 exponent>>=1;// 右移一位 } return n>=0?res:(1/res); }