前言
该系列文章为本人刷leetcode的记录,主要旨在分享刷题的思路及算法解析(尽可能的一题多解),另方便自己日后查阅回顾。代码的实现语言是python和go。
想进大厂免不了刷题,一起加油吧,小伙伴们!
题目
offer 第16题 数值的整数次方(medium)
链接: https://leetcode-cn.com/problems/shu-zhi-de-zheng-shu-ci-fang-lcof/
题目内容
实现pow(x,n),即计算x的n次幂(x^n)。不得使用库函数,同时不需要考虑大数问题
示例 1:
输入:x = 2.00000, n = 10
输出:1024.00000
示例 2:
输入:x = 2.10000, n = 3
输出:9.26100
示例 3:
输入:x = 2.00000, n = -2
输出:0.25000
解释:2-2 = 1/22 = 1/4 = 0.25
提示:
-100.0 < x < 100.0
-231 <= n <= 231-1
-104 <= xn <= 104
解题思路
实现pow(x,n),即计算x的n次幂(x^n)。不得使用库函数,同时不需要考虑大数问题
分析:计算x的n次幂;
解法1:递归法
解法2:非递归法:快速幂法
代码实现
python
class Solution:
def myPow(self, x: float, n: int) -> float:
#方法1:尾递归;该题很明显是阶乘相类似的问题;就是不断重复乘以x
#尾递归也会超时
flag=0
if n<0: n=-n;flag=1
def recur_tail(n,sum):
#迭代终止条件
if n==0:
if flag==1: return 1/sum
return sum
else:
return recur_tail(n-1,sum*x)
return recur_tail(n,1)
# 粗暴解法;直接循环
# sum =1
# for i in range(n):
# sum *=x
#return sum
#方法2:快速幂
#针对比如a^b 假如是3^11=3^(2^0+2^1+2^3)=(3^1)*(3^2)*(3^8);
#所以将原来算11次的现在缩短到计算三次即可;
#那么怎么计算这三项呢;实际上,上式的1,2,8都是表示b的二进制表示的第1,2,8位上为1;
#由15题可知对于b的二进制表示时有多少个1的求法我们已经知道了;
#那么本题就是每当b的二进制中第x位有1出现时就将a^x进行累乘就行;x位为0时不用累乘;(就是将原来的count++替换成a^x的累乘)
#
# flag=0
# if n<0:n=-n; flag=1
# ret =1
# a=x
# while n>0:
# if n&1:#如果第x位为1则需要纳入累乘
# ret *= a
# a *=a
# n >>=1
# if flag==1: ret=1/ret
# return ret
go
//整数的n次幂
func POW(x, n int) int{
//方法1:尾递归
//尾递归也会超时
flag := 0
if n<0{n=-n;flag=1}
var recur_tail func(n int,sum float64) float64
recur_tail = func(n int,sum float64) float64 {
//递归终止条件
if n == 0 {
if flag==1{return 1/sum}
return sum
}else{
return recur_tail(n-1,sum*x)
}
}
return recur_tail(n,float64(1))
//写一下递归
//递归终止条件
//if n==0{return 1
//}else{
// return x*POW(x,n-1)
//}
//方法2:快速幂方法
flag := 0
if n<0{n=-n;flag=1}
ret := float64(1)
for n>0{
if n&1==1{
ret *= x
}
x *=x
n >>=1
}
if flag==1{ret = 1/ret}
}
总结
注意快速幂的解法套路;需要熟练掌握; 注意这里需要考虑n<0的情况;