Pow(x, n)

  • 方法一:暴力法
  • 方法二:递归快速幂算法
  • 方法三:迭代快速幂算法
  • 方法四:位运算法

方法一:暴力法

思路

只需模拟将 x 相乘 n 次的过程。

如果 \(n < 0\),我们可以直接用 \(\dfrac{1}{x}\), \(-n\) 来替换 \(x , n\) 以保证 \(n \ge 0\)。该限制可以简化我们的进一步讨论。

但我们需要注意极端情况,尤其是负整数和正整数的不同范围限制。

算法

我们可以用一个简单的循环来计算结果。

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

复杂度分析

  • 时间复杂度:\(O(n)\)。我们将 x 相乘 n 次。
  • 空间复杂度:\(O(1)\)。我们需要一个变量来存储 x 的最终结果。

方法二:递归快速幂算法

class Solution {
public:
double fastPow(double x, long long n) {
if (n == 0) {
return 1.0;
}
double half = fastPow(x, n / 2);
if (n % 2 == 0) {
return half * half;
} else {
return half * half * x;
}
}
double myPow(double x, int n) {
long long N = n;
if (N < 0) {
x = 1 / x;
N = -N;
}
return fastPow(x, N);
}
};

复杂度分析

  • 时间复杂度:O(log(n))O(log(n))。每次我们应用公式$ (x ^ n) ^ 2 = x ^ {2 * n}\(,\)n$ 就减少一半。 因此,我们最多需要 \(O(log(n))\)次计算来得到结果。
  • 空间复杂度:\(O(log(n))\)。每次计算,我们都需要存储 \(x ^ {n / 2}\) 的结果。 我们需要计算 \(O(log(n))\)次,因此空间复杂度为 \(O(log(n))\)。

方法三:迭代快速幂算法

递归或迭代的快速幂实际上是实现同一目标的不同方式。

class Solution {
public:
double myPow(double x, int n) {
long long N = n;
if (N < 0) {
x = 1 / x;
N = -N;
}
double ans = 1;
double current_product = x;
for (long long i = N; i ; i /= 2) {
if ((i % 2) == 1) {
ans = ans * current_product;
}
current_product = current_product * current_product;
}
return ans;
}
};

复杂度分析

  • 时间复杂度:\(O(log(n))\)。对于 n 的每个二进制位,我们最多只能乘一次。所以总的时间复杂度为 \(O(log(n))\)。
  • 空间复杂度:\(O(1)\)。我们只需要两个变量来存储 x 的当前乘积和最终结果。

位运算实现pow(x,n)

根据暴力法的思路来看特别简单,但通过位运算呢?

位运算技巧

我举个例子吧,例如 n = 13,则 n 的二进制表示为 1101, 那么 m 的 13 次方可以拆解为:

\(m^{1101} = m^{0001} * m^{0100} * m^{1000}\)。

我们可以通过 & 1和 >>1 来逐位读取 1101,为1时将该位代表的乘数累乘到最终结果。直接看代码吧,反而容易理解:

int pow(int n){
int sum = 1;
int tmp = m;
while(n != 0){
if(n & 1 == 1){
sum *= tmp;
}
tmp *= tmp;
n = n >> 1;
}
return sum;
}

时间复杂度近为 \(O(logn)\),而且看起来很牛逼

幂次方的四种快速取法(不使用pow函数)的更多相关文章

  1. javascript——四种函数调用形式

    此文的目的是分析函数的四种调用形式,弄清楚函数中this的意义,明确构造函对象的过程,学会使用上下文调用函数. 在JavaScript中,函数是一等公民,函数在JavaScript中是一个数据类型,而 ...

  2. 执​行​o​r​a​c​l​e​函​数​的​四​种​方​法

    1.在定义函数时:如果有参数,则参数可有类型但是不加长度. 2.在执行函数: var/variable var_name var_type(如果数据类型是number则没有长度,如果数据类型是varc ...

  3. JavaScript (JS) 函数补充 (含arguments、eval()、四种调用模式)

    1. 程序异常 ① try-catch语法    测试异常 try-catch语法代码如下: try { 异常代码;     try中可以承重异常代码, console.log(“try”)  出现异 ...

  4. PHP URL参数获取方式的四种例子

    在已知URL参数的情况下,我们可以根据自身情况采用$_GET来获取相应的参数信息($_GET['name']);那,在未知情况下如何获取到URL上的参数信息呢? 第一种.利用$_SERVER内置数组变 ...

  5. DES算法与四种加密模式的代码实现(C++语言)

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/Love_Irelia97/article/ ...

  6. 横向对比分析Python解析XML的四种方式

    横向对比分析Python解析XML的四种方式 在最初学习PYTHON的时候,只知道有DOM和SAX两种解析方法,但是其效率都不够理想,由于需要处理的文件数量太大,这两种方式耗时太高无法接受. 在网络搜 ...

  7. 快速理解VirtualBox的四种网络连接方式

    VirtualBox中有4中网络连接方式: NAT Bridged Adapter Internal Host-only Adapter VMWare中有三种,其实他跟VMWare 的网络连接方式都是 ...

  8. php 冒泡 快速 选择 插入算法 四种基本算法

    php四种基础算法:冒泡,选择,插入和快速排序法 来源:PHP100中文网 | 时间:2013-10-29 15:24:57 | 阅读数:120854 [导读] 许多人都说 算法是程序的核心,一个程序 ...

  9. 快速了解yuv4:4:4 yuv4:2:2 yuv 4:1:1 yuv 4:2:0四种YUV格式区别

    四种YUV格式区别如下: 1.YUV  4:4:4抽样方式: Y: Y0 Y1 Y2 Y3 U: U0 U1 U2 U3 V: V0 V1 V2 V3 2.YUV   4:2:2抽样方式: Y   : ...

随机推荐

  1. tomcat 认证爆破之custom iterator使用

    众所周知,BurpSuite是渗透测试最基本的工具,也可是神器,该神器有非常之多的模块:反正,每次翻看大佬们使用其的骚操作感到惊叹,这次我用其爆破模块的迭代器模式来练练手[不喜勿喷] 借助vulhub ...

  2. Java方法(函数)

    4.1方法简介 方法是语句的集合,他们在一起执行一个功能: 1.方法是解决一类问题的步骤的有序组合(功能块) 2.方法包含于类与对象中 3.方法在程序中创建,在其它地方引用 4.原子性:单一职能原则( ...

  3. HTML5其他标签应用

    HTML5 是下一代 HTML 标准. HTML5 多媒体 音频标签 <audio src=" "></audio> 视频标签 <video src= ...

  4. Java基础单词总结

    单词总结 Actualpayment --- 实际付款   Aggregatemount --- 合计金额      MemberPoints --- 会员积分 Management --- 管理   ...

  5. 使用vuex做列表数据过滤

    功能需求 展示一个表格,表格包含选项有" 姓名 年龄 是否显示"三个列表项 是否显示列表项是可操作开关,点击切换打开/关闭 将表格中开关为打开状态的列表项,在另一个表格中显示 需求 ...

  6. Arch Linux, 无法启动进入sddm登录

    启动Arch Linux 的时候全屏就一个错误"Failed to start Load/Save Screen Backlight Brightness of backlight:acpi ...

  7. Spring学习之AOP的实现方式

    Spring学习之AOP的三种实现方式 一.介绍AOP 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能 ...

  8. 下载数据到csv中(乱码),使用numpy , pandas读取失败 解决方案

    读取数据,下载数据到 csv 文件中 allUniv 列表类型[[...],[...]] 字符集编码使用 utf-8-sig with open('文件名.csv','w',newline='',en ...

  9. PHP strnatcasecmp() 函数

    实例 使用"自然"算法来比较两个字符串(不区分大小写): <?php高佣联盟 www.cgewang.comecho strnatcasecmp("2Hello w ...

  10. luogu P4206 [NOI2005]聪聪与可可 期望dp 记忆化搜索

    LINK:聪聪与可可 这道题的核心是 想到如何统计答案. 如果设f[i][j]表示第i个时刻... 可以发现还需要统计位置信息 以及上一次到底被抓到没有的东西 不太好做. 两者的位置都在变化 所以需要 ...