LeetCode C++ 50. Pow(x, n)【Recursion】中等

Implement pow(x, n), which calculates x raised to the power n (i.e. xn).

Example 1:

Input: x = 2.00000, n = 10
Output: 1024.00000

Example 2:

Input: x = 2.10000, n = 3
Output: 9.26100

Example 3:

Input: x = 2.00000, n = -2
Output: 0.25000
Explanation: 2-2 = 1/22 = 1/4 = 0.25

Constraints:

  • -100.0 < x < 100.0
  • -231 <= n <= 231-1
  • -104 <= xn <= 104

题意:实现函数 double Power(double base, int exponent) ,求 baseexponent 次方。不得使用库函数,同时不需要考虑大数问题。


虽然不用考虑大数问题,但这不是意味着简单递归/迭代乘法,就能够完成这一道题——比如 1.00000 2147483647 ,顺序相乘绝对会超时。

解法1 递归快速幂

class Solution { 
public:
    double myPow(double x, int n) { 
        if (n == 0) return 1; //正数右移最后得到0
        if (n == 1) return x;
        if (n == -1) return 1 / x; //负数右移永远是负数,加一个判断
        double temp = myPow(x, n >> 1);
        if (n & 1) return temp * temp * x;
        else return temp * temp;
    }
};

运行效率如下:

执行用时:0 ms, 在所有 C++ 提交中击败了100.00% 的用户
内存消耗:6.1 MB, 在所有 C++ 提交中击败了28.57% 的用户

或者写成:

class Solution { 
public:
    double myPow(double x, int n) { 
        if (n == 0) return 1; //正数右移最后得到0
        if (n == 1) return x;
        if (n == -1) return 1 / x; //负数右移永远是负数 
        if (n & 1) return myPow(x, n - 1) * x;
        double temp = myPow(x, n >> 1);
        return temp * temp;
    }
};

解法2 迭代快速幂

class Solution { 
public:
    double myPow(double x, int n) { 
        double ans = 1, base = x;
        bool flag = (n >= 0);
        //负数取反,考虑到最小负数,需要先自增,后续再多除一个x
        if (!flag) n = -(++n); //或者使用longlong
        while (n) {
            if (n & 1) ans *= base;
            base *= base;
            n >>= 1; //n必须取正
        }
        return flag ? ans : 1 / ans / x;
    }
};

运行效率如下:

执行用时:0 ms, 在所有 C++ 提交中击败了100.00% 的用户
内存消耗:6.1 MB, 在所有 C++ 提交中击败了20.39% 的用户

或者一开始 n 不取正,而是使用 / 2 代替右移,这样不论正负 n 最终都会缩小到 0

class Solution { 
public:
    double myPow(double x, int n) { 
        double ans = 1, base = x;
        bool flag = (n >= 0);
        while (n) {
            if (n & 1) ans *= base;
            base *= base;
            n /= 2; //换成/2,不用担心负数问题
        }
        return flag ? ans : 1 / ans;
    }
};

运行效率如下:

执行用时:0 ms, 在所有 C++ 提交中击败了100.00% 的用户
内存消耗:6.3 MB, 在所有 C++ 提交中击败了8.13% 的用户
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页