LeetCode 123. Best Time to Buy and Sell Stock III| 动态规划

来源:互联网 发布:小说阅读网软件 编辑:程序博客网 时间:2024/06/10 15:14

题目描述

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.

e.g.

3 4 2 1 6 9 2 3 8

Best choice
buy at 4th day and sell at 6th day
and buy at 7th day and sell at 9th day

算法分析

这道题如果直接做会比较难想到直接的状态转移函数,但是如果我们把这个大问题转化为两个小的问题的话,就容易解决很多。我们可以把这个问题想成,选择一种方法在第 i 天前最多赚的钱 与 第 i 天后最多赚的钱之和最大。对于这两个子问题实际上容易解决很多。

对于第一个子问题:
我们设一个数组 pre,来保存在第 i 天前赚取最多的利润
我们再设置一个int类型min_buy来保存在第i 天前买入的最低价,然后用状态转移方程就可以算出第 i 天前的最大利润了

pre[1] = 0
pre[i] = max(pre[i-1], prices[i] - min_buy)
i = 2, 3,4, ……, n

对于第二个自问题:
我们可以类似的设一个数组 post, 来保存在第 i 天 后赚取最多的利润
然后类似设置一个int类型max_sell 来保存在第i天后卖出的最高价,然后用状态转移方程可以算出第 i 天 后的最大利润

post[n] = 0
post[i] = max(post[i+1], max_sell - prices[i])
i = 1,2 ,3 ,4, …… ,n-1

按照pre数组和post数组,我们只需要用O(N)的时间遍历一遍挑出
max{ pre[i] + post[i]} i = 1 ,2 ,3, …… n

这三部分的时间复杂度都是O(N), 所以这个算法总的时间复杂度就是O(N), 空间复杂度为O(N)

代码如下

int maxProfit(vector<int>& prices) {    vector<int> pre(prices.size()),post(prices.size());     int max_earn=0;     int min_buy = prices[0];     for(int i = 0 ; i < prices.size();i++){        min_buy = min(prices[i],min_buy);        max_earn= max(max_earn,prices[i]-min_buy);        pre[i] = max_earn;     }     max_earn = 0;     int max_sell = prices[prices.size()-1];     for(int i = prices.size()-1; i>=0 ; i--){        max_sell = max(prices[i],max_sell);        max_earn = max(max_earn,max_sell-prices[i]);        post[i] = max_earn;     }     int ans = 0;     for(int i = 0 ; i < prices.size(); i++){        ans = max(ans,pre[i]+post[i]);     }     return ans;} 
0 0
原创粉丝点击