大概题意:给定一个数组,数组的元素i表示第i天石头买入或者卖出的价格,求出能够赚到最多的钱的数目。注意不能在同一天买入和卖出。不限制买入卖出的次数。注意只有卖掉原来买入的石头之后才能再次买入,
这道题和LeetCode 121相似,但是不再限制买卖次数了。
这道题可以用贪心的做法来解答。找到每一段最长连续上升序列,在序列的第一天买入,在序列的最后一天卖出,这样就能达到利益的最大化。给个简单不太严谨的证明:首先在上升序列中买入卖出时不值得的,不会赚到更多的钱。例如序列1,2, 3, 4, 5, 6,只有以1的价格买入,以6的价格卖出,才能获得最大的利益。而在序列中买入,在序列之后卖出也不会赚到更多的钱。假如我在序列之后找到一个比序列最后一个元素还要大的元素卖出,这样会不会得到更好的结果呢?答案是不会的,因为序列之后的第一个元素是不会大于序列的最后一个元素的,如果我们选择在序列第一天买入,最后一天卖出,在之后的一天又买入,再在找到的元素更大的那一天卖出,这样收入会更多。在序列之前买入,序列之中卖出,或者在序列之前买入,序列之后卖出,简单的证明相似,就不再说明。这样一遍扫描就能得出结果,时间复杂度为O(n),代码如下:
# define INF 100000000
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n = prices.size() ;
if (n <= 1) return 0;
vector<int> a ;
a.push_back(INF) ;
for (int i=0; i<n; i++) a.push_back(prices[i]) ;
a.push_back(-INF) ;
int ans = 0 ;
int buy = 0 ;
for (int i=1; i<=n; i++) {
if (a[i] <= a[i-1]) buy = a[i] ;
else if (a[i] >= a[i+1]) {
ans += a[i] - buy ;
}
}
return ans ;
}
};