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;
    }
};

 

posted @ 2018-05-02 15:34  約束の空  阅读(118)  评论(0)    收藏  举报