Leetcode(50):Pow(x, n)

我们先考虑n是非负数的情况:


方法一:迭代法

double pow(double x, int n)
{
    int i;
    double sum = 1;
    for (i = 0; i < n; i++)
        sum *= x;
    return sum;
}

主要操作为乘法运算。

T(n) = n;

时间复杂度为O(n);


方法二:递归一

double pow(double x, int n)
{
    if (n == 0)
        return 1;
    if (n == 1)
        return x;
    else
        return  pow(x, n-1) * x;
}

主要操作为乘法运算。

T(n) = T(n-1) + 1;

T(1) = 0;

T(n) = n-1;

时间复杂度为O(n);


方法三:递归二(使用二分法)

double pow(double x, int n)
{
    if (n == 0)
        return 1;
    if (n == 1)
        return x;
    if (n % 2)
        return pow(x, n-1) * x; //也可以使用return pow(x, (n-1)/2) * pow(x, (n-1)/2) * x; 结果时间复杂度相同。
    else
        return pow(x, n/2) * pow(x, n/2);
}
主要操作为乘法运算。

先计算n为偶数的时间复杂度:

T(n)= 2T(n/2) + 1;

T(1) = 0;

T(2^k) = 2*T(2^(k-1)) + 1 = 2*(2*T(2^(k-2) + 1)) + 1 = 2^2 * T(2^(k-2)) + 2^1 + 1;

迭代可求得,T(2^k)= 2^k * T(2^0) + 2^(k-1) + 1;

T(n) = n/2 + 1;

时间复杂度为O(n);

n位奇数时的时间复杂度为:

T(n) = T(n-1) + 1;

因为n为奇数,那么n-1一定为偶数,所以T(n)= (n-1)/2 + 2 = n + 3/2;

时间复杂度为O(n);

所以,总的时间复杂度为O(n);


方法四:(递归,二分法,优化)

double pow(double x, int n)
{
    if (n == 0) return 1;
    if (n == 1) return x;
    double v = pow(x, n/2);
    if (n % 2)
        return v * v *x;
    else
        return v * v;
}

基本运算为乘法运算。

n为偶数时:T(n) = T(n/2) + 1;

n为奇数时:T(n) = T(n/2) + 2;

T(1) = 0;

使用上面类似的分析方法可得出时间复杂度为O(logn);


方法五:进一步优化

double pow(double x, int n)
{
    if (n == 0) return 1;
    if (n == 1) return x;
    if (n % 2) 
        return pow(x*x, n/2) * x;
    else
        return pow(x*x, n/2);
}
虽然这个算法的时间复杂度仍然是O(logn)。但是相对于方法三,速度会加快。


接着,考虑n为负数的情况

double myPow(double x, int n)
{
    if (n < 0)
        return 1.0/pow(x, -n);
    else
        return pow(x, n);
}
经过测试,除了方法一时间超时外,其他的都可以Accept。可见leetcode对时间复杂度的要求不是非常严格。


要考虑 0次方的问题

0的0次方有争议, 我们返回0

0的负数次方非法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值