0%

数值的整数次方


题目:

题解:

  • 解题思路:

  • 复杂度分析:

    • 时间复杂度 O(log_2 n) : 二分的时间复杂度为对数级别。
    • 空间复杂度 O(1) : res, b 等变量占用常数大小额外空间。
  • 代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    // 超时算法
    class Solution {
    public double myPow(double x, int n) {
    if (n == 0) {
    x = 1;
    }

    if (n < 0) {
    x = 1 / x;
    n = -n;
    }
    if (n > 0) {
    double a = x;
    for(int i = n; i > 1; i--) {
    x = x * a;
    }
    }
    return x;
    }
    }

    good算法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    // 快速幂法
    class Solution2 {
    public double myPow(double x, int n) {
    if (x == 0) {
    return 0;
    }

    // -n会溢出,但在long形态里面,还是表示的-2147483648,为什么呢?
    // n = -2147483648(对应计算机里的补码表示)
    // -n 对应计算机里面的真实(补码)表示,和n的补码表示一样,因为已经溢出了,表示不了了。
    // 因为根据求相反数的规则:对n求相反数,就对n进行从右往左数,第1个1不变,其他的二进制位变成相反数即可。
    // 参考百度百科补码表示:https://baike.baidu.com/item/%E8%A1%A5%E7%A0%81
    // int 取值范围 -2^31——2^31-1 -2147483648——2147483647
    // b = -n ; // b = -2147483648, 错误代码
    // b = -b; // b = 2147483648,正确代码,-b也可以在 正数范围内进行表示。
    // 所以必须使用long
    long b = n;
    double res = 1.0;
    if (b < 0) {
    x = 1 / x;
    b = -b;
    }
    while (b > 0) {
    // (与操作):判断末尾的二进制数是1还是0
    if ((b & 1) == 1) res *= x;
    x *= x;
    // (移位操作): nn 右移一位(可理解为删除最后一位)。
    b >>= 1;
    }
    return res;
    }
    }