188. Best Time to Buy and Sell Stock IV
problem description
Say you have an array for which the i-th element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete at most k transactions.
Note: You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
Example 1:
Input: [2,4,1], k = 2
Output: 2
Explanation: Buy on day 1 (price = 2) and sell on day 2 (price = 4), profit = 4-2 = 2.
Example 2:
Input: [3,2,6,5,0,3], k = 2
Output: 7
Explanation: Buy on day 2 (price = 2) and sell on day 3 (price = 6), profit = 6-2 = 4.
Then buy on day 5 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3.
algorithm thought
这是这系列的第四题,第一题是只能一次交易,第二题是可以任意次交易,第三题是可以两次交易,这三题都能O(n)时间内完成。这题是可以k次交易,其实在第三题(可以完成两次交易)已经可以从两次交易推出任意次交易的情况了。只是每次遍历到一个商品,就要进行k次交易,时间复杂度太高了,一共211个test cases在209个的时候TEL了。这种方法也会把代码贴出来
其实上面这个方法是可行的,但是还需要考虑优化。如果一共只有n个价格,那么最多就进行n/2次交易。换句话说,如果k>n/2,那么就可以认为可以进行任意次交易。将时间复杂度降到O(n).如果不这么处理的话,时间复杂度降是O(kn),空间复杂度也会达到O(k)。所以加一个短处理对时间复杂度影响挺大的
code
class Solution {
public:
int maxProfit(int k, vector<int>& prices) {
k=min(k,int(prices.size()));
vector<pair<int,int>> tc(k+1,make_pair(INT_MIN,0));
for(auto p:prices){
for(int i=1;i<=k;++i){
tc[i].first=max(tc[i].first,tc[i-1].second-p);
tc[i].second=max(tc[i].second,tc[i].first+p);
}
}
return tc.back().second;
}
};
//加了快速处理
class Solution {
public:
int maxProfit(int k, vector<int>& prices) {
if(k>prices.size()/2){
return shortPro(prices);
}
vector<pair<int,int>> tc(k+1,make_pair(INT_MIN,0));
for(auto p:prices){
for(int i=1;i<=k;++i){
tc[i].first=max(tc[i].first,tc[i-1].second-p);
tc[i].second=max(tc[i].second,tc[i].first+p);
}
}
return tc.back().second;
}
int shortPro(vector<int>&prices){
int res=0;
for(int i=1;i<prices.size();++i){
if(prices[i]>prices[i-1]){
res+=(prices[i]-prices[i-1]);
}
}
return res;
}
};
algorithm analysis
对于第一个算法,时间复杂度是O(kn)。对于第二个加了快速处理的方法,在LeetCode上运行时间能降到4ms,复杂度分析应该要用均摊分析。也不太了解,就不多分析了。
Last updated