Algorithm recursion

Posted by stanleybb on Mon, 27 Dec 2021 08:44:53 +0100

reference resources Boss blog

1. Understanding of recursion

Recursion is to call our own process. We don't have to worry about what each level does. We just need to pay attention to the implementation of a certain level, because each level is the same!!!

Recursion can be seen as a simplified version of a loop, and the essence of recursion can be seen as a loop

For example, A method A calls itself all the time. At this time, all the methods will be on A stack. When A certain method meets the termination conditions, the last called method, that is, the method at the top of the stack, will be executed and then out of the stack, and the result will be returned to the method calling it, that is, the method at the top of the stack will continue. Finally, the first method A will be executed, the stack will be empty, and the program will end

2. Recursive Trilogy

According to the above understanding of recursion, three steps to solve the recursion problem are summarized

  1. Find the termination condition of the whole recursion: when should the recursion end?
  2. Find return value: what information should be returned to the upper level?
  3. What should this level of recursion do: what should be done in this level of recursion?

3. Classic application of recursion

3.1 summation

Problem: write a method to pass in an integer n to find the sum of 1 to N. requirements: use recursion

The simplest way to solve this problem is to use the for loop and add it directly

We use recursion to solve this problem and find the sum of 1 to N, that is, the sum of n to 1

  • Step 1 - find the termination condition of recursion. The last operation is performed first, that is, n+(n-1) will be completed finally. When n=1, there is no need to recurse and return 1 directly
  • Step 2 - find the return value. We find the sum of n to 1. We must want to return n + (the sum of n-1 to 1)
  • Step 3 - what does this level recursion do: this level recursion is to add the numbers before N and n-1, and then return to the previous level

What each level does is to sum all the numbers after n+ n and then return

n n-1 n-2 ... 1

code implementation

public int sum(int n){
    	//Termination conditions
        if (n==1){
            return 1;
        //What each level does, the sum of this number + the number in front of him and returns
        }else {
            return n+sum(n-1);
        }
    }

3.2 factorial

Pass in an integer n and find the factorial from n to 1

Similar to 3.1

public int jc(){
    //End at 1
    if(n==1){
        return 1;
       //What each layer does is to return the product of the number of this layer * the previous number
    }else{
        return n*jc(n-1);
    }
}

3.3 Fibonacci series

Given an integer n, find the nth term of Fibonacci sequence

In the Fibonacci sequence, except the first two terms, each term is equal to the sum of its first two terms

0 1 1 2 3 5 8 13 21 ...

trilogy

We want n, we need n-1 and n-2....

Find termination conditions: because the first two items do not match, when recursion to n=0 or n=1, directly return the corresponding 0 or 1

The return value is the function of this method: the function is to find the value of the nth item

What should each level do: each level should return the sum of the first two items of this item to the previous level

public int fib(int n){
   	if(n==0) return 0;
    if(n==0) return 0;
    //What each level does is add up the first two terms of n
    else return fib(n-1) + fib(n-2);
}

3.4 traversing the linked list

The general traversal of linked lists is a loop. Here we use recursion to try

Find termination condition: return when null is reached

The return value is what this method does: output the value of each node

What should each level do: output the value of the current node

    public  void showData2(ListNode head) {
        if (head == null) {
            return;
        }
        System.out.println(head.val);
        showData2(head.next);
    }

3.5 reverse linked list

Force buckle problem solution

3.6 exchange nodes in linked list

Force buckle problem solution

3.7 delete duplicate elements in the linked list

Force buckle problem solution

3.7 project application: assembly three-level classification

Recursion is used in the assembly of three-level classification in the project of grain mall

Simulate three-level classification for assembly

To define an entity and judge whether a person instance has a parent category, it depends on its dadId. If the dadId is 0, it indicates that the instance is a and category, and the dadId of other instances is equal to the id of an instance

public class Person {
    
    //Primary key
    private Integer id;
    
    //Parent category id
    private Integer dadId;
    
    //Sub classification
    private List<Person> sons;

}

code implementation

trilogy

1. Termination condition when it reaches the last level of classification, it will terminate if it has no subcategory

2. Return value: the return value represents the next level of a classification

3. What to do at each level: now there is a level-1 classification. First find all its level-2 classifications, then find and set all the sub classifications of the level-2 classification, and finally return to the level-2 classification

  //Create some instances and install them with a List,
  List<Person> persons = new ArrayList();
  
    @Test
    public void Simulated three-level classification() {

        // Find all the first level classifications first
        List<Person> collect = persons.stream().filter(p -> p.getDadId() == 0).collect(Collectors.toList());

        //Traverse all the first level classifications and set the upper second level classification for each first level classification. The second level classification sets the upper first level classification
        List<Person> collect1 = collect.stream().peek(p -> p.setSons(get(persons, p))).collect(Collectors.toList());

    }

    //The recursive method sets all its sub classifications for a classification
    private List<Person> get(List<Person> persons, Person root) {
        //Termination condition ends when a category has no parent category
        if (root.getDadId() == null) {
            return null;
        }
        //First find all subcategories of this node, that is, all subcategories of root
        List<Person> tmp = persons.stream().filter(person -> root.getId().equals(person.getDadId())).collect(Collectors.toList());

        //Set the subcategory of the subcategory of this node to the subcategory
        //That is, find the subcategories of all subcategories of root and set them in the attribute
        List<Person> res = tmp.stream().peek(person -> person.setSons(get(persons, person))).collect(Collectors.toList());
        return res;
    }

3.8 quick sort

3.9 tree correlation

The subcategory of all subcategories to root and set it in the attribute
List res = tmp.stream().peek(person -> person.setSons(get(persons, person))).collect(Collectors.toList());
return res;
}

## 3.8 quick sort

## 3.9 tree correlation

Topics: Algorithm data structure recursion