每天一道LeetCode-----求一个数的n次方,n是很大很大的数,n用数组存储着
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;
};
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
