LeetCode 50 Pow(x, n)

题目描述

Pow(x, n)

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

示例 1:

输入:x = 2.00000, n = 10
输出:1024.00000

示例 2:

输入:x = 2.10000, n = 3
输出:9.26100

示例 3:

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

提示:

  • -100.0 < x < 100.0
  • -231 <= n <= 231-1
  • n 是一个整数
  • 要么 x 不为零,要么 n > 0
  • -104 <= xn <= 104

解法

解法1:类二分法 + 递归

比如x^64,可以按照下面顺序:

x→x2→x4→x8→x16→x32→x64

的顺序,从 x 开始,每次直接把上一次的结果进行平方,计算 6 次就可以得到结果。

再举一个例子,如果我们要计算 x^77,我们可以按照:

x→x^2→x4→x9→x19→x38→x77

的顺序,我们把上一次的结果进行平方后,还要额外乘一个 x。

直接从左到右进行推导看上去很困难,因为在每一步中,我们不知道在将上一次的结果平方之后,还需不需要额外乘 x。但如果我们从右往左看,分治的思想就十分明显了:

  • 当我们要计算 x^n 时,我们可以先递归地计算出 y=x^(n/2)
  • 根据递归计算的结果,如果 n 为偶数,那么 xn=y2;如果 n 为奇数,那么 xn=y2 * x
  • 递归的边界为 n=0,任意数的 0 次方均为 1。

由于每次递归都会使得指数减少一半,因此递归的层数为 O(log⁡n),算法可以在很快的时间内得到结果。

java代码:

class Solution {
    public double myPow(double x, int n) {
        long N = n;
        return N >= 0 ? quickMul(x, N) : 1.0 / quickMul(x, -N);
    }

    public double quickMul(double x, long N) {
        double ans = 1.0;
        // 贡献的初始值为 x
        double x_contribute = x;
        // 在对 N 进行二进制拆分的同时计算答案
        while (N > 0) {
            if (N % 2 == 1) {
                // 如果 N 二进制表示的最低位为 1,那么需要计入贡献
                ans *= x_contribute;
            }
            // 将贡献不断地平方
            x_contribute *= x_contribute;
            // 舍弃 N 二进制表示的最低位,这样我们每次只要判断最低位即可
            N /= 2;
        }
        return ans;
    }
}

复杂度

  • 时间复杂度:O(logn)
  • 空间复杂度:O(logn),即递归的层数

解法2:类二分法 + 迭代

舒勇迭代代替递归

java代码:

class Solution {
    public double myPow(double x, int n) {
        long N = n;
        return N >= 0 ? quickMul(x, N) : 1.0 / quickMul(x, -N);
    }

    public double quickMul(double x, long N) {
        double ans = 1.0;
        // 贡献的初始值为 x
        double x_contribute = x;
        // 在对 N 进行二进制拆分的同时计算答案
        while (N > 0) {
            if (N % 2 == 1) {
                // 如果 N 二进制表示的最低位为 1,那么需要计入贡献
                ans *= x_contribute;
            }
            // 将贡献不断地平方
            x_contribute *= x_contribute;
            // 舍弃 N 二进制表示的最低位,这样我们每次只要判断最低位即可
            N /= 2;
        }
        return ans;
    }
}

复杂度

  • 时间复杂度:O(logn)
  • 空间复杂度:O(log1)

你可能感兴趣的:(#,leetcode,leetcode,算法,数据结构)