总结:
快速幂思想,无论是矩阵快速幂,快速幂,还是快速乘
都是很好的算法
快速幂应该首先考虑的是他的递归形式(因为从左往右没有从右往左好想)
那么这个题目呢?
假设有一个数77 或者 64
x**77=(x**38)**2 * x
所以一旦无法整除,那么就需要补充一个x
可以整除就不需要
但是从左往右看的时候就没有那么明显的规律了
你需要找到规律
而在这里就是 奇数的时候需要进行一个记录
内置方法
def fun1(x,n):#啊这,它通过了
'''
这个题目
你当然可以一点一点的算
但应该是不能通过的
'''
return x**n
顺利超时代码
def fun2(x,n):
'''
我想了一下,我大概知道问题出在拿了
他**内置的方法里面的代码用的可能就是快速幂思想
所以我现在要写一个循环
顺利超时
:param x:
:param n:
:return:
'''
sum_ = 1
if n < 0:
x = 1 / x
for i in range(abs(n)):
sum_ *= x
return sum_
迭代版本的快速幂
def fun3(x,n):
'''
快速幂思想,可以更快更强
:param x:
:param n:
:return:
'''
if n==0:
return 1
if n<0:
x=1/x
n=abs(n)-1 #n=0 1 -1
result=x
while n>0:
if n%2!=0:
result*=x
x*=x
n//=2
return result
递归版本的快速幂
def fun4(x,n):
'''
递归思路
其实正常来讲应该是先写递归,再写迭代的这个代码
假如你要算 x**64
你很清楚 x→x2→x4→x 8→x16→x32→x64 这是你长久以来的计算能力
但是其他的数字呢?
所以从左往右看的时候你往往不知道什么时候需要多乘x
那么从右往左看呢?
假如有个数字77
77//2=38 余数为1
所以x**77=(x**38)**2 * x
这样就看的很舒服了
:param x:
:param n:
:return:
'''
if n < 0:
n = abs(n)
x = 1 / x
def digui(n):
# 基本结束条件
if n == 0:
return 1
if n % 2 != 0: # 不能整除2
return (digui(n // 2)) ** 2 * x
return digui(n // 2) ** 2
return digui(n)