Step jump basic version, improved version (can not jump 2 consecutive steps)

Algorithm jump steps basic version, improved version (can not jump 2 consecutive steps)

@author: Jingdai
@date:2020.11.15

Step jumping (frog jumping) is a very classic algorithmic problem. I saw an improved version of step jumping (can't jump 2 steps in a row) when I looked at the interview questions a few days ago. Now I will summarize it.

Before introducing the improved version of the solution, review the basic version. If you don’t want to see it, you can skip to the improved version.

Basic Edition

Title description

There is an n-step staircase. You jump from the bottom up, and you can jump 1 or 2 steps each time. How many ways can you jump to the top of the building?

Idea and code

This basic version is very simple. For the nth level, you only have two ways to jump up:

  1. Jump up from n-1 step 1
  2. Jump up from n-2 to 2

So you can get the recurrence:

Insert picture description here

Then you can use recursive method to solve or use dp method to solve. Look at the following code:

  • Recursive method (not recommended, high complexity, easy to time out when n is large)

    public int jumpStairs(int n) {
           
           
        if (n <= 3)
            return n;
        return jumpStairs(n-1) + jumpStairs(n-2);
    }
    
  • dp way

    public int jumpStairs(int n) {
           
           
        if (n <= 3)
            return n;
        int[] dp = new int[n];
        for (int i = 0; i < n; i++) {
           
           
            if (i <= 2) {
           
           
                dp[i] = i+1;
            } else {
           
           
                dp[i] = dp[i-1] + dp[i-2];
            }
        }
        return dp[dp.length-1];
    }
    

At the same time, when dp is found, only the result of the last n is needed, so you can optimize the space complexity and get the following code:

  • Optimize dp

    public int jumpStairs(int n) {
           
           
        if (n <= 3)
            return n;
    
        int prePre = 2;
        int pre = 3;
        int cur = 5;
        for (int i = 4; i <= n; i++) {
           
           
            cur = prePre + pre;
            prePre = pre;
            pre = cur;
        }
        return cur;
    }
    

At the same time, you will find that this recursive formula is the formula of the Fibonacci sequence, so you can also directly use the formula of the Fibonacci sequence to directly calculate it.

Improved version

Title description

The problem is basically the same. There is a staircase of n steps. You can jump up from the bottom. You can jump 1 or 2 steps each time, but you can't jump 2 steps twice in a row. How many ways can you jump to the top of the building?

Idea and code

Using the idea of ​​the previous basic version, for the nth level, you have only two ways to jump up:

  1. Jump up from n-1 step 1
  2. Jump up from n-2 to 2 steps (at the same time, n-2 must be jumped to 1 step)

There is one more restriction here: the state of n-2 from n-2 to n-2 must be from n-3 to n-2. Therefore, here, our dynamic programming not only saves the number of all methods that jump to the i-th order, but also saves the number of methods that jump to the i-th order in the last step by jumping to the first step. Used here f(n)represents the total number of skip method of n-th order, by g(n)showing the last step hop method jumps n-th order first order, thus obtaining recursive formula:

Insert picture description here

Based on this, you can write code, see the following code snippet.

public int modifiedJumpStairs(int n) {
     
     
        
    if (n <= 3)
        return n;

    // first total methods number
    // second last step is one step methods number
    int[][] dp = new int[n][2];

    dp[0][0] = 1; 
    dp[0][1] = 1;
    dp[1][0] = 2;
    dp[1][1] = 1;
    dp[2][0] = 3;
    dp[2][1] = 2;

    for (int i = 3; i < n; i++) {
     
     
        dp[i][0] = dp[i-1][0] + dp[i-2][1];
        dp[i][1] = dp[i-1][0];
    }
    return dp[dp.length-1][0];
}

Let us carefully observe the recurrence above.

Insert picture description here

As shown in the figure, the recursive substitution can be simpler. According to the conclusion, you can change the two-dimensional array into a one-dimensional array, see the code snippet below.

public int modifiedJumpStairs(int n) {
     
     

    if (n <= 3)
        return n;

    int[] dp = new int[n];

    for (int i = 0; i < n; i++) {
     
     
        if (i <= 2) {
     
     
            dp[i] = i+1;
        } else {
     
     
            dp[i] = dp[i-1] + dp[i-3];
        }
    }
    return dp[dp.length-1];
}

Of course, the above code can also be optimized, because only the last result is n, and none of the previous ones are needed, so the space complexity can be optimized to the O(1)following code.

public int modifiedJumpStairs(int n) {
     
     

    if (n <= 3)
        return n;

    int prePrePre = 1;
    int prePre = 2;
    int pre = 3;
    int cur = 4;
    for (int i = 4; i <= n; i++) {
     
     
        cur = pre + prePrePre;
        prePrePre = prePre;
        prePre = pre;
        pre = cur;
    }

    return cur;
}

Guess you like

Origin blog.csdn.net/qq_41512783/article/details/109711869