【LeetCode-数学】Pow(x, n)

题目描述

实现 pow(x, n) ,即计算 x 的 n 次幂函数。

输入: 2.00000, 10
输出: 1024.00000

输入: 2.10000, 3
输出: 9.26100

输入: 2.00000, -2
输出: 0.25000
解释: 2-2 = 1/22 = 1/4 = 0.25

说明:

  • -100.0 < x < 100.0
  • n 是 32 位有符号整数,其数值范围是 [−2^31, 2^31 − 1]

题目链接: https://leetcode-cn.com/problems/powx-n/

思路1

暴力求解。直接循环即可,需要注意 n<0 时,需要将 x=1/x 以及 n=-n. 代码如下:

class Solution {
public:
    double myPow(double x, int n) {
        if(n==0) return 1;
        long N = n;

        double ans = 1;
        if(N<0){
            x = 1/x;
            N = -N;
        }
        
        for(int i=0; i<n; i++) ans*=x;
        return ans;
    }
};
// 超时

要先把 n 转为 long,因为虽然 -2^31 在 int 范围内,但 2^31 超出了 int 的范围。由于 n 的范围是 [−2^31, 2^31 − 1] ,所以该解法超时未通过。

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

思路2

因为:

  • \(x^n = x^{n/2}*x^{n/2}\),n 为偶数;
  • \(x^n = x^{n/2}*x^{n/2}*n\),n 为奇数;

所以可以使用递归来做,类似于用递归写阶乘的方法:

class Solution {
public:
    double myPow(double x, int n) {
        if(n==0) return 1;
        long N = n;

        if(N<0){
            x = 1/x;
            N = -N;
        }

        return fastPow(x, N);
    }

    double fastPow(double x, int n){
        if(n==0) return 1;

        double half = fastPow(x, n/2);
        if(n%2==0) return half * half;
        else return half * half * x;
    }
};

这种方法被称为快速幂。这样写也行:

class Solution {
public:
    double myPow(double x, int n) {
        if(n==0 || x==1) return 1;

        bool isNegative = n<0?true:false;
        n = abs(n);
        double ans = fastPow(x, n); 
        if(isNegative) return 1/ans;
        else return ans;
    }

    double fastPow(double x, int n){
        if(n==0) return 1;
        if(n==1) return x;

        double half = fastPow(x, n/2);
        if(n%2==0) return half*half;
        else return half*half*x;
    }
};

需要注意的是,fastPow不能写成如下形式:

double fastPow(double x, int n){
    if(n==0) return 1;

    if(n%2==0) return fastPow(x, n/2)*fastPow(x, n/2);
    else return fastPow(x, n/2)*fastPow(x, n/2)*x;
}

上面的写法会重复计算fastPow(x, n/2)从而导致超时。

  • 时间复杂度:O(logn)
  • 空间复杂度:O(1)
posted @ 2020-05-07 16:03  Flix  阅读(256)  评论(0编辑  收藏  举报