Pow(x, n)
原题链接Pow(x, n)
给定一个数,求n次方。n次方可以分解成两个n/2次方相乘,所以递归即可。
class Solution {
public:
double myPow(double x, int n) {
bool negative = n < 0;
double res = helper(x, n);
return negative ? 1 / res : res;
}
private:
double helper(int x, int n)
{
if(n == 0)
return 1;
if(n == 1)
return x;
if(n % 2)
{
double res = helper(x, n / 2);
return res * res * x;
}
else
{
double res = helper(x, n / 2);
return res * res;
}
}
};
Super Pow
原题链接Super Pow
同样是求某个数的n次方,但是n存在数组中,如[1, 0]代表n为10。而且数组代表的n会非常大,有可能会超过int的范围,所以直接还原n然后计算n次方的方法基本是没戏了。
既然这样,就只能从每位下手,有这样一个公式
(a * b) % k = (a % k) * (b % k) % k
以数组为[1, 2, 3, 4, 5, 6, 7]为例,表示a的1234567次方,因为有
a ^ 1234567 = (a ^ 1234560) * (a ^ 7)
所以
(a ^ 1234567) % k = (((a ^ 1234560) % k) * ((a ^ 7) % k)) % k
而
(a ^ 1234560) % k = ((a ^ 123456) ^ 10) % k = (((a ^ 123456) % k) ^ 10 ) % k
所以
(a ^ 1234567) % k = (((((a ^ 123456) % k) ^ 10 ) % k) * ((a ^ 7) % k)) % k
将a ^ n % k
抽象为f(a, n)
函数,那么上式可以写成
f(a, 1234567) = f(f(a, 123456), 10) * f(a, 7) % k
可以发现,每次都可以把n的最后一位去除,从而减少n,当n为1或为0时返回即可。不过注意上面的式子对于n为[0 : 10]内的数都不需要再调用f
函数了,直接求就可以,也就是将外层f
改为pown
f(a, 1234567) = pown(f(a, 123456), 10) * pown(a, 7) % k
class Solution {
public:
int superPow(int a, vector<int>& b) {
if(b.empty())
return 1;
int back = b.back();
b.pop_back();
return pown(superPow(a, b), 10) * pown(a, back) % base_;
}
private:
int pown(int n, int k)
{
/*
* 因为n可能很大,这里实现取模防止在for循环result * n中溢出
* 比如result为第二次for循环后的某个数,而n为INT_MAX,乘完直接溢出
*/
n %= base_;
int result = 1;
for(int i = 0; i < k; ++i)
result = (result * n) % base_;
return result;
}
const int base_ = 1337;
};