Dynamic Programming on Intervals I (LeetCode #123)

In previous dynamic programming problems, we are only evaluating a part of the array starting from the beginnig and iteratively increasing the size of that part. But, what if we are required to evaluate the entire array from the start and somehow derive a value from it? What if we have to divide the entire array into parts and then calculate the sum? Let's have a look at today's problem.


LeetCode 123. Best Time to Buy and Sell Stock III

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

Find the maximum profit you can achieve. You may complete at most two transactions.

Note: You may not engage in multiple transactions simultaneously (i.e., you must sell the stock before you buy again).

Unlike its preceding questions, this time we are allowed to do at most two transactions. From knowledge of previous question, I only know how to continuosuly increase the size of the subarray and derive value from it. Then it got me thinking, is it possible for me to apply it here?

At first, all seems dull. We must find insight from the entire array because we have to find the two most valuable transactions. Our previous method can only support one transaction. But then, an idea struck me. Since we are allowed two transactions, there must be a middle point that divides the entire array into two, and then we would find the maximum profit from the two halves, allowing us to reuse the same method as in previous questions.

My approach to this is to create another dp array, in addition to the "traditional" one that starts from the beginnig, that, on the contrary, starts at the back. It will then iteratively increase its size at the front at find the maximium gain. The two arrays would then find the maximum profit starting at the two boundaries. Next, we will loop through all the middle points to find the sum of the two transactions, i.e. maximizing the sum of gains starting from left up to k and from k to the back, where k is the middle point. Since we are allowed to buy and sell stocks on the same day, using the same for the two dp arrays would be acceptable. If there were only one or no continuous increasing trend, we will simply get a 0.

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int dpl[prices.size() + 2]; // from start
        int dpr[prices.size() + 2]; // from back
        memset(dpl, 0, sizeof(dpl));
        memset(dpr, 0, sizeof(dpr));
        // keep track of the min and max in the two intervals
        int leftmin = prices[0], rightmax = prices[prices.size() - 1];
        // loop through index
        for(int i = 1 ; i <= prices.size(); i++){
            // update the two dp arrays in opposite directions
            dpl[i] = max(dpl[i-1], prices[i - 1] - leftmin);
            dpr[prices.size() + 1 - i] = 
                max(dpr[i+1], rightmax - prices[prices.size() - i]);
            // update the min and max
            leftmin = min(leftmin, prices[i-1]);
            rightmax = max(rightmax, prices[prices.size() - i]);
        }
        // stores the max profit
        int result = 0;
        // loop through the middle points
        for(int i = 1; i <= prices.size(); i++){
            result = max(result, dpl[i] + dpr[i]);
        }
        return result;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值