LeetCode 372. Super Pow problem solving ideas (super detailed)

This question is actually to investigate the fast power. The so-called fast power is actually the abbreviation of the modulo of the fast power. In short, it is to quickly find the power of a power (modulo). In the process of program design, it is often necessary to find the remainder of a large number for a certain number. In order to obtain a faster algorithm with a larger calculation range, a fast power modulus algorithm is generated.

Let's start with a simple example: seeking .

Algorithm 1. First, design this algorithm directly:

int ans = 1;
for(int i = 1;i<=b;i++)
{
   ans = ans * a;
}
ans = ans % c;

The time complexity of this algorithm is reflected in the for loop, which is O ( b ) . There are obvious problems with this algorithm. If a and b are too large, it will easily overflow.

So, let's take a look at the first improvement plan: before talking about this plan, we must first have such a formula:


  Everyone should have learned this formula in discrete mathematics or number theory.

So it was improved without thinking:

Algorithm 2 :

int ans = 1;
a = a % c; //加上这一句
for(int i = 1;i<=b;i++)
{
   ans = ans * a;
}
ans = ans % c;

Smart readers should be able to think that since a factor is multiplied and then multiplied and the remainder remains unchanged, then the newly calculated ans can also be taken as the remainder, so a better improved version is obtained.

Algorithm 3 :

int ans = 1;
a = a % c; //加上这一句
for(int i = 1;i<=b;i++)
{
   ans = (ans * a) % c;//这里再取了一次余
}
ans = ans % c;

This algorithm has no improvement in time complexity, it is still O (b), but it is much better, but under the condition that c is too large, it is still possible to time out, so we introduce the following fast power algorithm.

The fast power algorithm depends on the following obvious formula, which I will not prove.


With the above two formulas, we can draw the following conclusions:


Then we can get the following algorithm:

Algorithm 4 :

int ans = 1;
a = a % c;
if(b%2==1)
   ans = (ans * a) mod c; //如果是奇数,要多求一步,可以提前算到ans中
k = (a*a) % c; //我们取a2而不是a
for(int i = 1;i<=b/2;i++)
{
   ans = (ans * k) % c;
}
ans = ans % c;

We can see that we have changed the time complexity to O (b / 2). Of course, this will not cure the symptoms. But we can see that when we make k = (a * a) mod c , the state has changed, and the final result we require is mod c instead of the original  mod c , so we found that this process is possible Iterate. Of course, there will be one more a mod c for odd numbers , so in order to complete the iteration, when b is odd, we make up for the extra one by ans = (ans * a)% c; Part of it can be iterated.

After the iteration as above, when b = 0 , all the factors have been multiplied and the algorithm ends. Then it can be completed in O ( log b ) time. So, there is the final algorithm: fast power algorithm.

Algorithm 5 : Fast power algorithm

int ans = 1;
a = a % c;
while(b>0)
{
   if(b % 2 == 1)
      ans = (ans * a) % c;
   b = b/2;
   a = (a * a) % c;
}

The above ideas are transferred from http://www.doc88.com/p-5836182437827.html

The following is the program (C ++) that I implemented according to this idea:

class Solution {
public:

    bool notZero(vector<int>& b) {
        for(int i = b.size()-1; i >= 0; i--) {
            if(b[i] > 0) return true;
        }
        
        return false;
    }
    
    void div(vector<int>& b) {
        int tmp = 0;
        for(int i = 0; i < b.size(); i++) {
            b[i] += tmp*10;
            tmp = b[i] % 2;
            b[i] = b[i] / 2;
        }
    }
    
    int superPow(int a, vector<int>& b) {
        int ans = 1;
        
        a = a % 1337;
        
        while(notZero(b)) {
            if(b[b.size()-1] % 2 != 0) ans = (ans * a) % 1337;
            
            div(b);
            
            a = (a * a) % 1337;
        }
        
        return ans;
    }
};


Unfortunately, Time Limit Exceeded is displayed when submitting. . . But the idea of ​​playing is no problem.


发布了60 篇原创文章 · 获赞 44 · 访问量 34万+

Guess you like

Origin blog.csdn.net/beyond702/article/details/53222077