首页 > 其他分享 >50.Pow(x,n)

50.Pow(x,n)

时间:2024-01-21 12:55:07浏览次数:21  
标签:return Pow 50 long double quickMul ans contributor

1.题目介绍

2.题解

本题的方法被称为「快速幂算法」,有递归和迭代两个版本。这篇题解会从递归版本的开始讲起,再逐步引出迭代的版本。
当指数 n为负数时,我们可以计算 x^-n再取倒数得到结果,因此我们只需要考虑 n 为自然数的情况。

2.1 模拟(不推荐,时间复杂度过高)

思路

分为n>=0, n<0情况分别计算Pow(x,n)

代码

class Solution {
public:
    double myPow(double x, int n) {
        double ans = 1;
        int num = n >=0 ? n:-n;
        for(int i = 0; i < num; i++){
            ans *= x;
        }
        if(n < 0) ans = 1.0 / ans;
        return ans;
    }
};

2.2 快速幂 + 递归

思路


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

代码

class Solution {
public:
    double quickMul(double x, long long N) {
        if(N == 0) return 1.0;
        double y = quickMul(x, N / 2.0);
        return N % 2 == 0? y*y : y*y*x;
    }
    
    double myPow(double x, int n) {
        long long N = n; // 这里为何要强转为long long? 因为后面-n进行取反时,-2147483648(INT_MIN,整型最小值)进行取反操作,INT_MIN 的取反结果会导致溢出,产生未定义的行为。
        return N >= 0 ? quickMul(x, N): 1.0 / quickMul(x, -N); 
    }
};

2.3 快速幂 + 迭代

思路

由于快速幂的核心理念是每次将上次的结果平方,相当于x(2n) ,但由于在中间乘上额外的x,我们不知道何时触发导致迭代写起来比较麻烦
但是我们仔细观察发现,将初始的x和后面额外乘上的x分开平方
\(x^n=x^{2^{i_0}}\times x^{2^{i_1}}\times\cdots\times x^{2^{i_k}}\)
最后化简可以得到
\(n=2^{i_0}+2^{i_1}+\cdots+2^{i_k}\)
其实就是n的二进制表达式,我们只要n在二进制位为1的值位置
就知道何时要额外乘一个x了

比如像n = 10(1010)是,其实就是2^2 * 2^8
所以我们可以维护一个值专门记录 2^n 的值 x_contributor
当n % 2 == 1时,我们就将结果记录值ans *= x_contributor即可


代码

class Solution {
public:
    double quickMul(double x, long long N) {
        double ans = 1.0;
        double x_contributor = x;
        while(N > 0){
            if(N % 2 == 1) ans *= x_contributor;
            x_contributor *= x_contributor;
            N /= 2.0;
        }
        return ans;
    }

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

标签:return,Pow,50,long,double,quickMul,ans,contributor
From: https://www.cnblogs.com/trmbh12/p/17977748

相关文章

  • (powershell 7) 安装及 Pycharm 上的配置
    1.windows上更新powershell下载地址(此处需要爬下墙): https://github.com/PowerShell/PowerShell选择一个LTS版本直接手动安装,完成完成后,会自动添加到PATH中,如果没有,可以手动配置#打开powershell$PSVersionTable.PSVersion 2.Pycharm配置powershell Note......
  • 代码随想录算法训练营第 十 一 天| 20. 有效的括号 1047. 删除字符串中的所有相邻重
    LeetCode 20.有效的括号题目链接:20.有效的括号思路:采用栈数据结构解题;遇到左括号,压右括号入栈 LeetCode 1047.删除字符串中的所有相邻重复项题目链接:1047.删除字符串中的所有相邻重复项注意:Java中队列实现类API的使用 LeetCode 150.逆波兰表达式求值题目链......
  • spring boot一个奇怪的错误(There was an unexpected error (type=Internal Server Err
    今天运行springboot的时候爆了这个错(Therewasanunexpectederror(type=InternalServerError,status=500).Exceptionparsingdocument:template=“index”,line6-column3)说什么无法解析文档,昨天还运行的好好的,看一下控制台说什么meta标签没关闭,我可是用idea自己创......
  • CF1850B
    签到题,按照题意模拟即可。遍历整个数组,当$a_i\le10$时,用\(b_i\)更新最大值即可。#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;signedmain(){intT,n,a,b,ans,mx;cin>>T;while(T--){mx=0;ans......
  • CF1850C
    要找到这个单词,就要先找到这个单词的开头,在输入时即可判断。根据题意,保持列数不变,增加行数,直到不为字母,输出途经的字母即构成了单词。#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;chara[9][9];signedmain(){intT,x,y,pd;cin>>T;......
  • CF1850F
    不难想到,可以枚举每个\(a_i\)的倍数,并用一个数组统计出现次数,最后求最大值,理论时间复杂度\(O(n\logn)\)。但如果\(a_i\)较小且重复出现,可能退化到\(O(n^2)\)。因此可以做一个小优化:对于每个\(a_i\len\),提前统计出每个数出现的次数,枚举倍数时只计算一次,可以提升计算效率......
  • CF1850D
    根据题意,不难想到贪心,将\(a\)从小到大排序,使得相邻两数之差的绝对值尽可能小。若存在两数之差的绝对值大于\(k\),则将两数之间作为一个“分界线”。在确定所有“分界线”后,序列被分成了多个子段,这些子段中最多保留一个才能满足条件。根据贪心,选择保留最长的一段,用\(n\)减去其......
  • SP2150
    不难想到,求区间和可以先\(O(n)\)预处理前缀和,后面就能做到对于区间\([l,r]\)可以\(O(1)\)求出\(\sum_{i=l}^ra_i\)。接下来考虑如何求解答案。设预处理后的前缀和数组\(sum_i=\sum_{j=1}^ia_j\)。区间\([l,r]\)满足要求,当且仅当\(sum_r-sum_{l-1}=47\)成立。将上......
  • DCDC应用电路方案中MOS管如何选型?30V60V100V150V
    MOS管在DCDC恒压/恒流电路中扮演着重要的角色。DCDC恒压电路用于将一个直流电源的电压转换为另一个恒定的电压输出。DCDC恒流电路则用于将一个直流电源的电流转换为另一个恒定的电流输出。MOS管在电路中的工作原理管在这些电路中通常用作开关元件,通过调整其栅极电压来控制导通和截......
  • (12)Powershell中变量的类型
    (12)Powershell中变量的类型WindowPowershell中变量的类型与Java,C#等高级语言中变量的类型不一样,可以不用显示指定Powershell中变量的类型,即Powershell中的变量具有更大的灵活性。Powershell中的变量采用.NetFramework类型。默认情况下,当变量只有一个值时,变量的数据类型由赋......