4

This topic aims to share some interesting or valuable topics found in the process of brushing Leecode. [Of course, the answer is based on js].

Dynamic programming is also one of the key types of leetcode's moderately difficult exercises, and may also be one of the interview hotspots, so its importance is self-evident.

image.png

topic related

  • Original title address: https://leetcode-cn.com/problems/dui-cheng-de-er-cha-shu-lcof/
  • Topic description:

    Example 1:
    Input: [7,1,5,3,6,4]
    Output: 5
    Explanation: Buy on day 2 (stock price = 1), sell on day 5 (stock price = 6), maximum profit = 6-1 = 5. (Note that the profit cannot be 7-1 = 6, because the sell price needs to be greater than the buy price.)
    - Example 2:
    Input: [7,6,4,3,1]
    output: 0
    Explanation: In this case, no trade is completed, so the maximum profit is 0.
    - Limit:
  • <= array length <= 10^5

Analysis of ideas

Brute force

First of all, some students liked it and a wave of 161fbdfe81003f brute force cracking , and directly calculated all possible combinations:

梭哈老头原图.png

Find the largest difference (i.e., the largest profit) between two numbers in a given array. In addition, the second number (sell price) must be greater than the first number (buy price), then all combinations are n*(n-1)/2 , and the complexity is O(n^2), no doubt, given in the title 0 <= Array length <= 10^5, proper timeout; and if brute force cracks , it is estimated that brute force pass .

dynamic programming

(The name sounds very scientific!)

In fact, early wrote in detail the basic idea of dynamic programming : https://segmentfault.com/a/1190000022309155
It is recommended that students who are unfamiliar can read this article first.

The core of the so-called dynamic programming the multi-stage process into a series of single-stage problems; the problem is continuously disassembled into sub-problems to solve .

If you have read the basics, you should know that the disassembly mentioned here is actually more straightforward to find the relationship between the i-th sub-problem of

This is actually brought into the questions put to solve n days buying and selling stocks most profitable problem, first into first solving most profitable time to sell the stock on n days, and then find out the maximum value for .

image.png

Take the input [7,1,5,3,6,4] as an example:

  1. If you sell on the first day, the maximum profit is 0, which is equal to no transaction;
  2. If you sell on the second day, the maximum profit is 0, because the price on the second day is 1, which is higher than the first day and will not trade;
  3. If you sell on the third day, the maximum profit is 4, that is, buy on the second day and sell on the third day;
  4. And so on...

To observe the calculated solving the most profitable time to sell the stock on day i, can get core, long known a record low so far , then highest profit before i day is actually using the i-th day minus this historical low price, so the idea is not coming?

image.png

var maxProfit = function(prices) {
  const profit = []; // profit[i] 表示第i天卖出时的最大利润 
  let historyMinPrice = Infinity;

  for(let i = 0; i <= prices.length; i++) {
      // 保持更新迄今为止的历史最低价
      if(prices[i] < historyMinPrice) {
        historyMinPrice = prices[i];
      }
      profit[i] = prices[i] - historyMinPrice;
  }
  // 未完待续
  // ... 
};

So, with this price after array, just get them maximum , in fact, is required for the output subject. This must not beat you, you can get a direct comparison cycle, but in fact, under the thinking, it did not need to make another loop, because in the original cycle, we can actually follow idea of the history of the lowest , in addition to maintain A maximum profit so far variable. that is

var maxProfit = function(prices) {
  const profit = []; // profit[i] 表示第i天卖出时的最大利润 
  let historyMinPrice = Infinity;
  let maxProfit = 0;

  for(let i = 0; i <= prices.length; i++) {
      // 保持更新迄今为止的历史最低价
      if(prices[i] < historyMinPrice) {
        historyMinPrice = prices[i];
      }
      profit[i] = prices[i] - historyMinPrice;
      if(profit[i] > maxProfit) {
        maxProfit = profit[i];
      }
  }
   return maxProfit;
};

image.png

Can it be better?

Now that we've solved the problem, is that enough? Looking back at our code, to maintain the existence of the profit array? Its meaning is only for updating maxProfit so is it not...

Be bold! Just remove it! !

var maxProfit = function(prices) {
  // 干掉profit[i] 
  let historyMinPrice = Infinity;
  let maxProfit = 0;

  for(let i = 0; i <= prices.length; i++) {
      // 保持更新迄今为止的历史最低价
      if(prices[i] < historyMinPrice) {
        historyMinPrice = prices[i];
      }

      if(prices[i] - historyMinPrice > maxProfit) {
        maxProfit = prices[i] - historyMinPrice;
      }
  }
   return maxProfit;
};

Is it a deeper sense of achievement here?

image.png

So the answer to this question is over here, see you next time!

image.png


安歌
7k 声望5.5k 粉丝

目前就职于Ringcentral厦门,随缘答题, 佛系写文章,欢迎私信探讨.