LeetCode 121. Best Time to Buy and Sell Stock
直接做
one-pass,一边找最低的价格,一边找最大的gap,就是我们最大的profit。
class Solution { public: int maxProfit(vector<int>& prices) { int maxPro=0, minPrice=INT_MAX; for (auto price:prices){ minPrice = min(minPrice,price); maxPro = max(maxPro, price-minPrice); } return maxPro; } };
Kadane's Algorithm
class Solution { public: int maxProfit(vector<int>& prices) { int n=prices.size(); if (n==0 || n==1) return 0; vector<int> diff(n,0); for (int i=1;i<n;++i) diff[i] = prices[i]-prices[i-1]; int maxEndingHere=diff[0]; int maxSoFar=diff[0]; for (int i=1;i<n;++i){ maxEndingHere = max(maxEndingHere+diff[i],diff[i]); maxSoFar = max(maxSoFar,maxEndingHere); } return maxSoFar; } };
同样是 Kadane's Algorithm,另一种理解思路:
和53题最大子串和一样的题目,把买入到售出当做一个子序列想就一模一样了。DP方程如下:
f[i]:以a[i]作为抛出日的最大profit (和最大字串和一样,以a[i]结尾的最大profit)
dp[i]:下标0~i过程中最大profit
令x为买入时的价格a
f[i] = max{ a[i]-x a[i]在交易内 在a[i]售出
0 } 此时x<-a[i] a[i]在交易内 在a[i]买入并售出
dp[i] = max{ f[i] a[i]在交易内
dp[i-1] a[i]不在交易内
由于f[i]和dp[i]之和上一个状态有关,所以可以压缩存储空间。且f[i]函数非常简单,写代码的时候可以直接放在dp[i]中写。(上面单独写出来方便整理思路)
网上很多代码中维护一个min_price,其实就是上述买入时的价格x,体会一下。个人感觉还是动态规划的思路最清楚,化简以后和网上别的思路是一样的。
class Solution { public: int maxProfit(vector<int>& prices) { if (prices.size()==0) return 0; int max_so_far=0; int min_price=prices[0]; for (int i=1;i<prices.size();++i){ if (prices[i]<min_price){ min_price = prices[i]; }else{ max_so_far = max(max_so_far, prices[i]-min_price); } } return max_so_far; } };

浙公网安备 33010602011771号