导读:算法哥最近在头条号上面分享一些有趣的算法题,但是通过前面两次分享,算法哥发现粉丝的回馈不多,不知道是不是题目难度选取问题,今天来个简单点的,你准备好了吗?
题目描述:
你的任务是计算 a^b 对 1337 取模,a 是一个正整数,b 是一个非常大的正整数且会以数组形式给出。
示例 1:
输入: a = 2, b = [3]输出: 8
示例 2:
输入: a = 2, b = [1,0]输出: 1024
题目分析:
咋一看,这不是水题一道吗?在算法哥眼里确实是真真的大水题,但是对于初学者来说,这有几个问题需要解决:
- 题目里的数字b是一个非常大的数,如果比long long的类型还大怎么办 ?
- 数字b很大,按照常规思路,求a^b mod 1337,如果b=10^9,那么岂不是需要做10^9次方次乘法?
不卖关子了,聪明的读者可能已经看出是个水题,拂袖而去了......
解题思路:
对于问题1,我们可以采取java的bigInterger大整数类来解决,怎么偷懒怎么来,哈哈,也可以用C/C++等,不过需要自己实现大数运算,算法哥样样兵器略懂一二,直接java的bigInteger搞定!
对于问题2,有个小技巧,举个例子,比如需要计算2^16次方,我们可以直接把2乘以2做16次乘法运算,也可以利用二分的思想,快速计算,假设我现在知道了2^8,我需要计算2^16次方,是不是我直接把(2^8) * (2^8)相乘就出来了,也就是说从2^8到2^16次方,只需要一次乘法就可以了,现在问题变成怎么计算2^8,同理,如果我知道了2^4岂不是也只需要一步乘法就搞定了,(2^4) *(2^4)=2^8,同理继续类推,要求2^16,只需要求2^8,2^4,2^2,2^1了,而2^1=0。相信读者已经知道怎么快速计算a^b了吧?废话不说了,直接上源码,一目了然!
![12d982f02c3a828e3bbc52f223d043f8.png](https://img-blog.csdnimg.cn/img_convert/12d982f02c3a828e3bbc52f223d043f8.png)
超级次方源码
复杂度分析:
很显然,计算a^b次方,我们可以通过计算a^(b/2)来得到a^b次方,复杂度显然是O(logn)的,聪明的读者,你想到了吗?
题目总结:
二分法,可能读者们对二分查找这些概念比较熟悉,实际上二分的思路在解决算法题上有很多妙用,在以后的文章里,算法哥还会介绍一些更有趣的,通过二分的思路去解决的题目,粉丝们请点击关注吧!