每天一道LeetCode-----求一个数的n次方,n是很大很大的数,n用数组存储着

来源:互联网 发布:xboxone 淘宝 编辑:程序博客网 时间:2024/04/30 03:43

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;};
阅读全文
0 0
原创粉丝点击