数值的整数次方问题

265 阅读2分钟

小知识,大挑战!本文正在参与「程序员必备小知识」创作活动。

问题

数值的整数次方

实现 pow(x, n) ,即计算 x 的 n 次幂函数。不得使用库函数,同时不需要考虑大数问题。

力扣链接

leetcode-cn.com/problems/sh…

考察要点

考察我们对于幂运算以及递归思想的使用

学会将递归思想转换为循环思想解题

思路1

通过for循环来实现, 依次将结果值乘以基数x, 执行n次

时间复杂度为O(n)

缺点: 没有考虑基数为0, 指数为负数的情况

代码1

 public double myPow(double x, int n) {
     double res = 1;
     for (int i = 0; i < n; i++) {
         res *= x;
     }
     return res;
 }

思路1 - 改进版

对于基于进行判断, 如果基数为0, 则直接返回0

对于指数进行判断, 如果为负数, 要进行相应的处理

代码1 - 改进版

 public double myPow(double x, int n) {
     if (x == 0) {
         return 0;
     }
 ​
     if (x == 1) return 1;
 ​
     double res = 1;
 ​
     // 判断指数n的正负
     for (int i = 0; i < (n < 0 ? -n : n); i++) {
         res *= x;
     }
     
     // 判断指数n的正负
     return (n < 0 ? (1 / res) : res);
 }

思路2 - 递归方式

假如求3的8次方

那就相当于求 ((3的4次方)的平方)

也就相当于求 (((3的2次方)的平方)的平方)

如果n为奇数数, 那么结果再乘以基数x就好

缺点: 如果指数n很大的情况下, 会导致栈溢出

代码2 - 递归方式

 public double myPow(double x, int n) {
     // 如果基数x为0, 那么指数为负数的话应该判定错误的输入
     if (x == 0) {
         return 0;
     }
 ​
     double res = 1;
     int abs = n > 0 ? n : -n;
 ​
   // 如果指数n为负数, 则要对结果进一步处理
     return (n > 0 ? power2(x, abs) : (1 / power2(x, abs)));
 }
 ​
 public double power(double x, int n) {
     // 递归基
     if (x == 0) return 0;
     if (n == 1) return x;
     
     // 求x的n次方, 相当于求x的n/2次方的结果, 再进行平方
     double res = power(x, n >> 1);
     
     // 对x的n/2次方结果再进行平方
     res *= res;
 ​
     // 如果n为奇数, 结果要再乘以基数x
     if ((n & 1) != 0) {
         res *= x;
     }
     return res;
 }

思路3 - 循环方式

基于公式

如果指数n为偶数 xn = (x2)n/2

如果指数n为奇数 xn = (x2)n/2 * x

代码3 - 循环方式

 public double myPow(double x, int n) {
     // 如果基数x为0, 则直接返回0
     if (x == 0) return 0;
 ​
     double res = 1;
 ​
     if (n < 0) {
         x = 1 / x;
         n = -n;
     }
 ​
     while (n > 0) {
       // 当n为奇数时, 将基数乘入结果res中
         if ((n & 1) != 0) res *= x;
       // 现在问题就变成了求(x的平方)的(n / 2)问题
       // 比如: 求3的8次方, 现在就变成了求9的4次方问题
        n >>= 1;
         x *= x;
        
     }
     return res;
 }

总结

通过本题我们可以更深入的了解求幂问题, 对于基数0和指数为负的时候的条件判断. 对于递归的使用, 以及将递归转换为循环的思想. 考察我们的思考严谨性以及对于负面数据的处理问题.