关闭

Leetcode(50):Pow(x, n)

标签: leetcodeC语言
232人阅读 评论(0) 收藏 举报
分类:

我们先考虑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的负数次方非法

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:14612次
    • 积分:762
    • 等级:
    • 排名:千里之外
    • 原创:61篇
    • 转载:7篇
    • 译文:2篇
    • 评论:2条