每日刷题(4)——剑指 Offer 16. 数值的整数次方

本篇文章题目来源于leetcode

前言

哈喽,大家好,我是小雨,今天做了一些剑指 Offer的题目,其中 16. 数值的整数次方 写了4版代码才通过,给我留下了深刻的印象。此题对时间的要求简直严格,但是从另一方面也给了做题者突破自己,优化代码的强大动力,非常不错。本文就对此题进行细致的分析吧!

Question 剑指 Offer 16. 数值的整数次方

实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,xn)。不得使用库函数,同时不需要考虑大数问题。

示例 1:

输入:x = 2.00000, n = 10
输出:1024.00000

提示:

  • -100.0 < x < 100.0
  • -231 <= n <= 231-1
  • -104 <= xn <= 104

Solution

这题的尝试了很多思路,大部分都超时了,最后使用快速幂算法进行解题,具体的思维过程如下:

1.看到这道题,首当其中的就是暴力法,即首先判断n是否是负数,如果是负数那么后续要进行倒数的操作,随后需要求解x的N次方的值,根据n的次数,反复执行*x的操作即可,代码如下,结果超时,后续的思路主要优化求解x的N次方的值,对正负判定不做优化。

2.我们可以发现x的N次方等于x的(N/2)次方乘以x的(N-N/2)次方,所以我们只需要求出x的(N/2)次方的值 y 即可,再求出y*y即可得出结果,代码如下,还是超时。

3.再次观察,发现其实只有最后一步进行了优化,x的(N/2)次方的值还是用累乘得出。再次优化,我们可以使用递归,把求x的N次方转化为求x的(N/2)次方x的(N-N/2)次方,形成了类似树的结构,进行递归操作即可得出答案,代码如下,还是超时!

4.再次观察,发现递归中,使用了类似树的结构,是先求左边,再求右边,递归求解,但是实际上,只需要求一边的结果(如左边)即可,另一边的结果可以通过左边的结果得出来!其实到这一步,就是快速幂算法了,代码如下,终于成功通过。

Code

//第一种思路

func myPow(x float64, n int) float64 {
	flag := false 
	if n < 0 {
		flag = true
		n = -n 
	}
	temp := x
    x = 1 
	for i := 0; i < n; i++ {
		x*=temp
	}
	if flag {
		x = 1/x 
	}
    return x

}

//第二种思路

func myPow(x float64, n int) float64 {
	flag := false 
	if n < 0 {
		flag = true
		n = -n 
	}

	temp := x
	x=1

	if n %2 == 0 {
		for i := 0; i < n/2; i++ {
			x*=temp
		}
		x *=x
	}else {
		for i := 0; i < n/2; i++ {
			x *= temp
		}
		x *=x
		x *=temp
	}
	
	
	
	
	if flag {
		x = 1/x
	}
	
	
return x

}

//第三种思路

func myPow(x float64, n int) float64 {
	flag := false
	if n < 0 {
		flag = true
		n = -n
	}
	var dfs func(n int)float64
	
	dfs = func(n int) float64 {
		if n == 0 {
			return 1 
		}else if n == 1 {
			return x
		}
		
		l:=dfs(n/2)
		r:=dfs(n-(n/2))
		return l * r
	}
	x = dfs(n)

	if flag {
		x = 1/x
	}
	return x
}

//第四次思路
func myPow(x float64, n int) float64 {
	flag := false
	if n < 0 {
		flag = true
		n = -n
	}
	var dfs func(n int)float64
	
	dfs = func(n int) float64 {
		if n == 0 {
			return 1 
		}else if n == 1 {
			return x
		}
		
		y := dfs(n/2) 
        if n%2 == 0 {
            return y*y
        }else{
            return y*y*x
        }

	}
	x = dfs(n)
	if flag {
		x = 1/x
	}
	return x
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雨雨不怕雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值