Best Time to Buy and Sell Stock III(Leetcode)

Best Time to Buy and Sell Stock III(Leetcode)

Say you have an array for which the ith element is the price of a given stock on day i.

Design an algorithm to find the maximum profit. You may complete at most two transactions.

Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

解题思路:

动态规划。用二位数组 v[j][i] 表示考虑到第 i 个数的第 j 次 transaction 的最大值。

考虑如何得到 v[j][i] 。对于第 i 个数有两种情况:

①卖出的第 i 天的股票。这就需要在第 i 天之前要买进股票,所以从第 i-1 天开始往前面找。对于历遍的数又有两种情况:

a. 该数值小于第 i 天股票的值。所以可以得到 v[j][i] = max(v[j][i], v[j-1][t-1] + prices[i] - prices[t]) 。(t是往回找的数的下标)

b. 该数值大于等于第 j 天股票的值。这种情况下可以得到 v[j][i] = max(v[j][i], v[j][t])。然后直接break跳出往回找的循环就可以了。

    因为该数值(第 t 天的值)大于等于第 i 天的值,也就是说第 t 天和第 i 天不可能构成一次transaction,而第 t 天之后的数值在往回找的过程中已经历遍了,所以此时第 i 天只能和第 t 天之前的某一天构成一次transaction。但是因为 prices[t] > prices[j] ,所以此时 v[j][t] > v[j][i] 。

②不卖出也不买入第 j 天的股票。v[j][i] = v[j][i-1] 。


代码:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        return maxProfit(prices, 2);
    }
    int maxProfit(vector<int>& prices, int n) {
        if (prices.size() == 0) return 0;
        vector<vector<int>> v(n, vector<int>(prices.size(), 0));
        for (int i = 1; i < prices.size(); ++i) {
            for (int j = 0; j < n; ++j) {
                v[j][i] = v[j][i-1];
                for (int t = i-1; t >= 0; --t) {
                    if (prices[t] < prices[i]) {
                        if (j == 0 || t == 0) {
                            v[j][i] = max(v[j][i], prices[i] - prices[t]);
                        } else {
                            v[j][i] = max(v[j][i], prices[i] - prices[t] + v[j-1][t-1]);
                        }
                    } else {
                        v[j][i] = max(v[j][i], v[j][t]);
                        break;
                    }
                }
            }
        }
        return v[n-1][prices.size()-1];
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值