Also implemented a recursive Fibonacci number, the interviewer will despise you to death

       The Fibonacci a column refers to a number of columns 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765 , 10946,17711,28657,46368 ......

       I remember learning C language, the university teachers often talk about using some common mathematical problems and recursive, which Fibonacci number is sure to be out of example. In later work, job interviews face questions of time, that there will be a large probability to write algorithms Fibonacci Amount column evaluated. I can say that on our road program, write algorithms Fibonacci column every programmer will definitely do one thing. Yesterday to go to the next line Tencent classroom activities organized by the activities have a guest, is the founder of a classroom, a lecturer algorithm course, we talked about this issue, considered to subvert my perception of the problem. In this paper, according to explain these lecturers, to analyze and sort out the problem to achieve algorithm.

       Below, we look at several common algorithms which analyze and efficiency.

 

  1, recursion

       Through observation, we find that one of the law, the value of the first and second terms are 1, behind each of the first two values ​​are the sum of so many of us will basically be implemented using a recursive common the algorithm is as follows:

1 public int fib(int n) {
2     if (n == 1 || n == 2) {
3         return 1;
4     }
5     return fib(n - 2) + fib(n - 1);
6 }

This code looks very simple and elegant, I think most of us are also usually written so now, before the author has been so written, and in my knowledge, there is only reserves aware of such an algorithm.

        In fact, when n is still relatively small, with a recursive method to implement is no problem, but when n is slightly larger when, for example, when n = 45, we look at its results by the test code execution :

1 MyClass myClass = new MyClass();
2 long t1 = System.currentTimeMillis();
3 int n = 45;
4 int result = myClass.fib(n);
5 long t2 = System.currentTimeMillis();
6 System.out.println("n=" + n + ";result=" + result + ";time=" + (t2 - t1));

The results obtained are:

n=45;result=1134903170;time=2881

We found that the implementation of this code, the time spent is 2881ms. If the value is bigger then, as n = 48:

n=48;result=512559680;time=11746

Time to reach the 11s more than a! If n is slightly larger then the time is consumed to exponential growth, for example, when n = 64, time may be consumed two or three centuries! Do not believe it, readers can try!

       So, it is very terrible, we thought no problem looks both simple and elegant algorithm actually is so time-consuming, it is simply some garbage code.

       We use a simple map to analyze the implementation of the algorithm to n = 6 as an example:

 

       We find that f (n) This method is called many times, and in which repetition rate is very high, that is double-counted many times, if n is slightly larger tree will be very large. Here we can see that each node needs to be calculated once, the number is calculated the total number of nodes of the binary tree, showing its time complexity is O (2 n- ), is exponential, which is the space complexity binary tree height is O (n). In this way, we should be clear on why this code efficiency so low the bar. 

 

  2, the array Preservation Act (the name is its own command)

       In order to avoid repeated many times, you can start up is calculated from n = 1, and each of the calculated data with a stored array, taken directly from the final value needed to the array, the algorithm is as follows:

1 public int fib(int n) {
2     int[] fib = new int[n];
3     fib[0] = 1;
4     fib[1] = 1;
5     for (int i = 2; i < n; i++) {
6         fib[i] = fib[i - 2] + fib[i - 1];
7     }
8     return fib[n - 1];
9 }

We were also taken n = 45 and n = 48 to look at the results of

n=45;result=1134903170;time=0
n=48;result=512559680;time=0

Consumption time is 0 (the time I get here is accurate to ms level, the time difference before and after 1ms or less, so the calculated result here is zero, the actual time-consuming, not 0, follow-up does not go into details), you can see execution efficiency has improved a lot. The algorithm for a main loop, the time complexity is O (n), need to open up a period of length n array, so the space complexity is also O (n), which greatly based on the above algorithms enhance efficiency.

 

  3, variable Preservation Act (also naming their own)

       Although the above algorithm is very efficient, but we still find a problem, in fact, the entire array, only need the latest three values ​​each calculation, the value of the previous calculation after it is no longer needed. For example, the calculation of the 10th, the array space is required, only the first two spaces 8 and 9, the first to the front space 7 in fact no longer necessary. So we also can improve the data stored by the three variables, the following algorithm:

 1 public int fib(int n) {
 2     int first = 1;
 3     int second = 1;
 4     int third = 2;
 5     for (int i = 3; i <= n; i++) {
 6         third = first + second;
 7         first = second;
 8         second = third;
 9     }
10     return third;
11 }

Still time complexity O (n), the spatial complexity level 3 is constant, i.e., the spatial complexity is 0, so this method is very efficient.

 

  4, the official method

       In fact, seeking Fibonacci number has a value formula:

The algorithm can be implemented by this formula:

1 public int fib(int n) {
2     double c = Math.sqrt(5);
3     return (int) ((Math.pow((1 + c) / 2, n) - Math.pow((1 - c) / 2, n)) / c);
4 }

Its time complexity and space complexity depends on the JDK achieve these mathematical formulas, and the efficiency is very high:

n=48;result=512559680;time=0

 

       Through the above analysis, we write algorithms when Fibonacci column, you can select the first and fourth three kinds according to the actual situation.

       If readers found this article described incorrectly or the wrong place, please let us know, thank you very much!

 

Guess you like

Origin www.cnblogs.com/andy-songwei/p/11707142.html