PigyChan_LeetCode 剑指 Offer 16. 数值的整数次方

剑指 Offer 16. 数值的整数次方

难度中等

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

示例 1:

输入: 2.00000, 10
输出: 1024.00000
示例 2:

输入: 2.10000, 3
输出: 9.26100
示例 3:

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

说明:
* -100.0 < x < 100.0
* n 是 32 位有符号整数,其数值范围是 [−231, 231 − 1] 。

分析:

(1)当指数为负数时,结果为整次方计算后的倒数

优化:

(1)2 ^ 4可以是222*2,也可以是2^2 * 2^2
(2)当n是偶数时,num^n = num^(n/2) * num^(n/2)
(3)当n是奇数时,num^n = num^(n/2) * num^(n/2+1)

代码(爆栈了):
    class Solution {
    public:
        double myPow(double x, int n) {
            if (n == 0) return 1;
            if (x == 1.0) return x;
            bool needInverse = n < 0 ? true : false;
            n = abs(n);
            double rst = helper(x, n);
            if (needInverse) {
                rst = 1.0 / rst;
            }
            return rst;
        }
        double helper(double x, int n) {
            if (n == 0) return 1;
            if (n == 1) return x;
            double returnVal = helper(x, n >> 1);
            returnVal *= returnVal;
            if (n & 0x1 == 1) returnVal *= x;
            return returnVal;
        }
    };

转而使用栈替递归

代码(TM的超时):
    class Solution {
    public:
        double myPow(double x, int n) {
            if (n == 0) return 1;
            if (x == 1.0) return x;
            bool needInverse = n < 0 ? true : false;
            n = abs(n);
            stack<bool> isOdd;
            while (n != 1) {
                if (n & 0x1 == 1) isOdd.push(true);
                else isOdd.push(false);
                n = n >> 2;
            }
            double rst = x;
            while (!isOdd.empty()) {
                rst = rst*rst;
                //如果这次需要得到的是奇数次方
                if (isOdd.top()) {
                    rst = rst * x;
                }
                isOdd.pop();
            }
            if (needInverse) {
                rst = 1.0 / rst;
            }
            return rst;
        }
    };

问题总结:
(1)使用栈记录n的自乘轨迹也需要消耗大量的时间空间成本
(2)直接在取得n自乘轨迹的途中,边取边为我们的结果相乘

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


            long num = n;
            double rst = 1;
            if (n < 0) {
                num = -num;
                x = 1 / x;
            }


            while (num) {
                if (num & 1) rst *= x;
                x *= x;
                num >>= 1;
            }


            return rst;
        }
    };



在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值