作者介绍:10年大厂数据\经营分析经验,现任大厂数据部门负责人。
会一些的技术:数据分析、算法、SQL、大数据相关、python
欢迎加入社区:码上找工作
作者专栏每日更新:
LeetCode解锁1000题: 打怪升级之旅
python数据分析可视化:企业实战案例
备注说明:方便大家阅读,统一使用python,带必要注释,公众号 数据分析螺丝钉 一起打怪升级
题目描述
实现 pow(x, n)
,即计算 x
的 n
次幂函数(即,(x^n))。
输入格式
- x:浮点数,底数。
- n:整数,指数。
输出格式
- 返回
x
的n
次幂。
示例
示例 1
输入: x = 2.00000, n = 10
输出: 1024.00000
示例 2
输入: x = 2.10000, n = 3
输出: 9.26100
方法一:快速幂(递归)
解题步骤
- 基本情况:处理
n
为0和负数的情况。 - 递归处理:利用快速幂算法,分治思想将问题规模减半,利用 (x^n = (x{n/2})2) 的性质来减少计算次数。
完整的规范代码
def myPow(x, n):
"""
使用快速幂算法(递归版本)来计算 x 的 n 次幂
:param x: float, 底数
:param n: int, 指数
:return: float, x 的 n 次幂
"""
if n == 0:
return 1
if n < 0:
x = 1 / x
n = -n
return myPow(x*x, n//2) if n % 2 == 0 else x * myPow(x*x, (n-1)//2)
# 示例调用
print(myPow(2.00000, 10)) # 输出: 1024.00000
print(myPow(2.10000, 3)) # 输出: 9.26100
算法分析
- 时间复杂度:(O(\log n)),每次递归将问题规模减半。
- 空间复杂度:(O(\log n)),递归栈的深度。
方法二:快速幂(迭代)
解题步骤
- 处理特殊情况:当
n
为0时,直接返回1。 - 迭代计算:使用位运算优化乘幂过程,通过不断地平方底数并根据指数的奇偶性决定是否乘以当前底数。
完整的规范代码
def myPow(x, n):
"""
使用快速幂算法(迭代版本)来计算 x 的 n 次幂
:param x: float, 底数
:param n: int, 指数
:return: float, x 的 n 次幂
"""
if n == 0:
return 1
elif n < 0:
x = 1 / x
n = -n
result = 1
while n > 0:
if n % 2 == 1:
result *= x
x *= x
n //= 2
return result
# 示例调用
print(myPow(2.00000, 10)) # 输出: 1024.00000
print(myPow(2.10000, 3)) # 输出: 9.26100
算法分析
- 时间复杂度:(O(\log n)),虽然是迭代但每次操作减半问题规模。
- 空间复杂度:(O(1)),使用常数空间。
方法三:暴力法(超时)
解题步骤
- 直接乘法:简单地使用循环,将
x
乘以自身n
次。
完整的规范代码
def myPow(x, n):
"""
使用暴力法计算 x 的 n 次幂,易超时
:param x: float, 底数
:param n: int, 指数
:return: float, x 的 n 次幂
"""
if n == 0:
return 1
if n < 0:
x = 1 / x
n = -n
result = 1
for _ in range(n):
result *= x
return result
# 示例调用
print(myPow(2.00000, 10)) # 输出: 1024.00000 (可能超时)
print(myPow(2.10000, 3)) # 输出: 9.26100 (可能超时)
算法分析
- 时间复杂度:(O(n)),直接乘法的次数等于指数。
- 空间复杂度:(O(1)),使用常数空间。
方法四:分治法
解题步骤
完整的规范代码
def myPow(x, n):
"""
使用分治法计算 x 的 n 次幂
:param x: float, 底数
:param n: int, 指数
:return: float, x 的 n 次幂
"""
if n < 0:
x = 1 / x
n = -n
if n == 0:
return 1
half = myPow(x, n // 2)
return half * half if n % 2 == 0 else half * half * x
# 示例调用
print(myPow(2.00000, 10)) # 输出: 1024.00000
print(myPow(2.10000, 3)) # 输出: 9.26100
算法分析
- 时间复杂度:(O(log n)),递归深度减半。
- 空间复杂度:(O(log n)),递归栈空间。
方法五:迭代二进制展开
解题步骤
- 二进制表示:通过 n 的二进制表示来决定哪些幂次需要计算。
- 迭代计算:对 x 进行连绑的平方,根据 n 的二进制位决定是否乘入结果。
完整的规范代码
def myPow(x, n):
"""
使用二进制展开的迭代法计算 x 的 n 次幂
:param x: float, 底数
:param n: int, 指数
:return: float, x 的 n 次幂
"""
if n < 0:
x = 1 / x
n = -n
result = 1
current_product = x
while n > 0:
if n % 2 == 1:
result *= current_product
current_product *= current_product
n //= 2
return result
# 示例调用
print(myPow(2.00000, 10)) # 输出: 1024.00000
print(myPow(2.10000, 3)) # 输出: 9.26100
算法分析
- 时间复杂度:(O(log n)),二进制展开的迭代次数。
- 空间复杂度:(O(1)),使用常数空间。
不同算法的优劣势对比
特征 | 方法一: 快速幂(递归) | 方法二: 快速幂(迭代) | 方法三: 暴力法(超时) | 方法四: 分治法 | 方法五: 二进制展开迭代 |
---|---|---|---|---|---|
时间复杂度 | (O(log n)) | (O(log n)) | (O(n)) | (O(log n)) | (O(log n)) |
空间复杂度 | (O(log n)) | (O(1)) | (O(1)) | (O(log n)) | (O(1)) |
优势 | - 逻辑简单 | - 空间效率高 | - 实现简单 | - 递归易理解 | - 高效且易实现 |
劣势 | - 空间消耗大 | - 需理解迭代 | - 易超时 | - 空间消耗相对较大 | - 需要理解二进制操作 |
应用示例
计算金融产品收益:
在金融领域,经常需要计算复利收益,例如计算一笔投资在固定年利率下的多年总收益。通过使用快速幂算法,可以高效地计算出 年化的值,从而快速得到投资收益预测。
# 计算年利率为5%的10年投资收益
annual_rate = 1.05
years = 10
investment_return = myPow(annual_rate, years)
print(f"10年后的投资收益倍数: {investment_return:.2f}") # 输出: 1.63
图形渲染和游戏开发:
在图形渲染和游戏开发中,经常需要进行坐标转换或是计算物体在不同角度下的位置。这种场景下,旋转矩阵的快速计算尤为关键,尤其是在需要快速大量计算时。使用快速幂算法可以高效地计算旋转矩阵的幂,进而实现快速的几何变换。
import numpy as np
def rotation_matrix(theta):
"""
计算给定角度的二维旋转矩阵
:param theta: float, 旋转角度(弧度)
:return: np.array, 旋转矩阵
"""
return np.array([
[np.cos(theta), -np.sin(theta)],
[np.sin(theta), np.cos(theta)]
])
# 计算45度旋转对应的矩阵的10次幂
theta = np.pi / 4 # 45度角的弧度值
rot_matrix = rotation_matrix(theta)
rot_matrix_pow = np.linalg.matrix_power(rot_matrix, 10) # 使用 NumPy 的矩阵幂函数
print("旋转矩阵的10次幂结果:\n", rot_matrix_pow)