notes/OJ notes/pages/Leetcode Best-Time-To-Buy-And-Sell-Stock.md
2022-09-03 15:17:25 +08:00

3.2 KiB

Leetcode Best-Time-To-Buy-And-Sell-Stock

2022-06-11


Data structures:

#DS #array

Algorithms:

#algorithm #Kadane_s_algorithm

Difficulty:

#leetcode #coding_problem #difficulty-easy


Problem

You are given an array prices where prices[i] is the price of a given stock on the ith day.

You want to maximize your profit by choosing a single day to buy one stock and choosing a different day in the future to sell that stock.

Return the maximum profit you can achieve from this transaction. If you cannot achieve any profit, return 0.

Examples

Example 1:

Input: prices = [7,1,5,3,6,4]
Output: 5
Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
Note that buying on day 2 and selling on day 1 is not allowed because you must buy before you sell.

Example 2:

Input: prices = [7,6,4,3,1]
Output: 0
Explanation: In this case, no transactions are done and the max profit = 0.

Constraints

  • 1 <= prices.length <= 105
  • 0 <= prices[i] <= 104

Thoughts

Firstly I thought of brute forcing, which is O(n * (n-1)) Then, I came up with dynamic programming, but this is still not so optimized Lastly, from here I know We can use Kadane's algo.

Tip

In Kadane's algorithm:

  • buyprice = min(buyprice, price[i]) // Achieve best min price
  • profit = max(profit, price[i] - buyprice) // find best profit ==so far==

To explain that, in each iteration, there are two cases:

  • if the current price is the lowest, set the buyprice to the lowest one
  • if the current price minus the buyprice is bigger tham profit, record that to profit.

So, the magic part happens at setting the buyprice, because the best profit will and only will occur after the lowest buyprice is set, thus we can find best solution in one run.

Solution

Time O(2n) Space O(n) solution (inefficient reverse kadane's algorithm)

class Solution {
public:
  int maxProfit(vector<int> &prices) {
    // Dynamic programming. and hash table.
    int size = prices.size();
    unordered_map<int, int> localmax;
    int max = 0;

    // populate localmax: max value after this one
    // the first one
    localmax[size - 1] = prices[size - 1];
    for (int i = size - 2; i >= 0; i--) {
      localmax[i] = std::max(prices[i + 1], localmax[i + 1]);
    }

    for (int i = 0; i < size; i++) {
      if (localmax[i] - prices[i] > max) {
        max = localmax[i] - prices[i];
      }
    }
    return max;
  }
};

Kadane's algorithm, Time O(n) Space O(1)

class Solution {
public:
  int maxProfit(vector<int> &prices) {
    // Kadane's algorithm
    // buyprice == min(buyprice, prices[i])
    int buyprice = INT_MAX;
    int profit = 0;

    for (int i = 0; i < prices.size(); i++) {
      buyprice = min(buyprice, prices[i]);

      profit = max(prices[i] - buyprice, profit);
    }

    return profit;
  }
};