Original: A daily walkthrough of the classical Algorithm--the third question the monkey eats the Peach
The monkey picked a few peaches on the first day, ate half of it, and ate one more. The next morning to eat the rest of the peach half, or not a lot of fun
Ate one. After every day eat the rest of the last half and add one. By the 10th day there was just one left. Q. How many peaches did the monkeys pick on the first day?
Analysis: This is a very classical algorithm problem, this topic embodies the idea of recursive ideas in the algorithm, recursion has two forms, push and reverse, for recursion, as long as
We find the recursive formula and the problem is solved.
Make s10=1, easy to see s9=2 (s10+1), simplify
S9=2s10+2
S8=2s9+2
.....
Sn=2sn+1+2
Thinking back gongjing that year, the teacher said recursion is the most concise, the most easy to understand, good, use recursion to try:
1 class Program2 {3 Static voidMain (string[] args)4 {5 intsum = Sumpeach (1);6 7Console.WriteLine ("The first day picked Peaches: {0}", sum);8 9 Console.read ();Ten } One A //Recursive - Static intSumpeach (intDay ) - { the if(Day = =Ten) - return 1; - - return 2* Sumpeach (Day +1) +2; + } -}
When we play transmitting return, the teacher said that linear recursion will be "variable, parameter, return value" in the process of "handing" the stack, if the delay "hand" is not the end, the stack will accumulate more,
Finally, the system default stack space in window is 1M.
So what's the solution? Tail recursion, below we continue on the code:
1 class Program2 {3 Static voidMain (string[] args)4 {5 intsum = Sumpeachtail (1,1);6 7Console.WriteLine ("The first day picked Peaches: {0}", sum);8 9 Console.read ();Ten } One A //Tail recursion - Static intSumpeachtail (intDayintTotal ) - { the if(Day = =Ten) - returnTotal ; - - //calculates the current value to pass to the next layer + returnSumpeachtail (Day +1,2* Total +2); - } +}
So what's the difference between the two types of recursion? Speak.
We can clearly see the difference between "linear recursion" and "tail recursion", so what is the essential difference? The end recursion in the process of each downward recursive, will be the current
The result of the layer is calculated and passed down a layer, in theory, after the next layer, the parameter value of the previous layer is no longer necessary, you can clear the previous layer of the variables accounted for
Use of the stack space, then the final effect is never appear stackoverflowexception, but actually whether this effect, it depends on whether the compiler
Really optimized for you.
Let's change day=10 to Day=int. MaxValue, run the program to see:
Unfortunately, there is a picture of the truth, throw an exception, of course, I am a rookie, has not read the assembly, we can also discuss the discussion, at present I personally think the C # compiler did not give
I do this optimization:-D.
The next step is to calculate the time complexity of this recursion, and the time complexity of "recursion" is about three main types:
1. Substitution method.
2. Recursive tree method.
3. Main theorem.
In this article I will say the substitution law, as follows
①: Guess the upper or lower bounds of recursive complexity.
②: Use mathematical induction to prove that your complexity is correct.
In order to have universality, we will "monkey eat peach" problem in turn, that is known S1, Seek S10, of course, the principle is the same, the general formula has the following form:
Tn=2tn-1+2①
Suppose Tn=o (n) ②
There must be a natural number of c>0 to make
Tn<=co (n) =cn③
③ into ① knowledge
TN<=2C (n-1) +2=2cn-2c+2
=cn-c+1
=cn-(c-1)
When c>=1, there must be TN<=CN
Finally, we conclude that the time complexity of recursion is O (N).
The daily walkthrough of the classic Algorithm question--the third question the monkey eats the Peach