LeetCode Elementary Algorithm Training-Dynamic Programming (Conquering...)

Introduction

Previous: LeetCode Elementary Algorithm Training-Sorting and Searching

Next: LeetCode Elementary Algorithm Training-Design Problem

Originally I wanted to start with the beginner and intermediate level and corporate interview algorithms, but in the end we chose to start from the basics, because we did not brush questions for the purpose of brushing questions, but exercise a kind of algorithm thinking in the process of brushing questions, after a lot of training Form a unique insight into the algorithm, cultivate the sensitivity to the algorithm, see the problem, a blueprint for solving the problem can appear in the brain, and slowly build confidence from the beginning, and this is also for the complex algorithm behind Lay the foundation for problem-solving ideas.

Introduction to LeetCode Primary Algorithm

If you also want to train your own algorithmic thinking, you can also join me, starting from the elementary algorithm, start your algorithm journey: elementary algorithm .

Some of your own thinking: Don’t just look at the answer after reading the question, and then recite the question, so that the memory of the implemented algorithm is not strong, you must have your own thinking; and don’t write on IDEA at the beginning, Be sure to try to write it on the whiteboard provided by leetCode and finally put it on IDEA to see if there are any problems, so as to consolidate your basic API usage and proficiency; another point is to be bold, not the cost of trial and error for the interview Low, try to incorporate our ideas into the code

Due to space issues, the blog only lists examples and your own problem-solving answers. For details, you can directly click on the topic to view.

Climb stairs

Suppose you are climbing stairs. It takes n steps to reach the top of the building.
You can climb 1 or 2 steps each time. How many different ways do you have to climb to the top of a building?

注意:给定 n 是一个正整数。

示例 1:
输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
1.  1 阶 + 1 阶
2.  2 阶

示例 2:
输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1.  1 阶 + 1 阶 + 1 阶
2.  1 阶 + 2 阶
3.  2 阶 + 1 阶

The idea of ​​dynamic programming: There are only two situations for the last step of climbing stairs, one is to take one step, the other is to take two steps, f(x) = f(x-1) + f(x -2), and we only need to know With the number of methods in the first and second layers, we can calculate the n-layer.

My first thought was recursion, but it timed out. It took 4.638s when n=45, which was quite slow.

class Solution {
    public int climbStairs(int n) {
        if(n == 1) return 1;
        if(n == 2) return 2;
        
        return climbStairs(n - 1) + climbStairs(n - 2);
    }
}

If recursion fails, change iteratively and use a for loop.

class Solution {
    public int climbStairs(int n) {

        if(n == 1) return 1;
        if(n == 2) return 2;
        
        int stepNMinus1 = 1;
        int stepNMinus2 = 2;

        for(int i = 3 ; i <= n; i++){
            int t = stepNMinus1;
            stepNMinus1 = stepNMinus2;
            stepNMinus2 = t + stepNMinus2;
        }
        return stepNMinus2;
    }
}

45/45 passed test cases
Status: Passed
Execution time: 0 ms
Memory consumption: 36.6 MB

In fact, it can be further optimized, using matrix fast power or Benets Fomula formula calculation, but these two involve the calculation of the matrix, and make up this later. It is too difficult to learn high numbers again.

The best time to buy and sell stocks

Given an array, its i-th element is the price of a given stock on the i-th day.

If you are only allowed to complete one transaction at most (that is, buy and sell a stock at once), design an algorithm to calculate the maximum profit you can make.

Note: You cannot sell stocks before buying them.

示例 1:
输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
     注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。
     
示例 2:
输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

We only need to consider how much money I made by selling today. When the price is lower, I will update the minimum value of the previous purchase and wait until the next day to sell. Each time I compare with the maximum profit of the previous day. And replace the maximum profit. The last maximum is the maximum profit.

This is a very ideal state of buying stocks. For real stocks, it is impossible for you to never see which ones you should buy in the past and which ones should not be bought, and you have bought the lowest point in history.

class Solution {
    public int maxProfit(int[] prices) {
        if(prices == null || prices.length == 0) return 0;

        int low = prices[0];
        int maxProfit = 0;

        for(int i = 1; i < prices.length; i ++){

            maxProfit = prices[i] - low > maxProfit ? prices[i] - low : maxProfit;

            if(prices[i] < low){
                low = prices[i];
            }
        }
        return maxProfit;
    }
}
Maximum subsequence sum

Given an integer array nums, find a continuous sub-array with the largest sum (the sub-array contains at least one element), and return the largest sum.

示例:
输入: [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。

Advanced:

If you have already implemented a solution with O(n) complexity, try to use a more subtle divide-and-conquer solution.

Guess you like

Origin blog.csdn.net/u011148116/article/details/107861417