力扣:买股票的最佳时机 II

47 阅读3分钟

6e6d6c5c-ab0a-4b74-ba19-4ae6338b7e22.png

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n = prices.size();
        if(n<1) return 0;
        int dp[n];
        dp[0]=0;
        for(int i=1;i<n;i++){
            for(int j = 0;j<i;j++){
                dp[i]= max(dp[i-1],prices[i]-prices[j]+dp[j]);
            }
        }
        return dp[n-1];
    }
};

第一次看到这个题目,想着是用dp来写的,算法时间复杂度是O(n²)。
状态转移方程

dp[i]= max(dp[i-1],prices[i]-prices[j]+dp[j]);

后来发现其实这个写法其实并不算是dp,只是单纯的暴力算法。
这个题用贪心的话其实就可以写出来了

int maxProfit(vector<int>& prices) {
    int ans = 0;
    int n=prices.size();
    for(int i=1;i<n;i++){
        if(prices[i]>prices[i-1])
            ans+=prices[i]-prices[i-1];
    }
    return ans;

思路就是我们每一天都可以进行买卖,那么我们只需要一直买上涨的股票,就能一直赚,并得到最大利益,因为一天内我们既可以买入又可以卖出,是没有利益损失的。

举个例子【7,1,5,3,4,6】

  1. 股价为1的那天,我们可以看到对比昨天股价7是跌的,所以我们不在股价为7的那天买入股票
  2. 股价为5的那天,我们可以看到对比昨天股价1是涨的,所以我们要买股价为1的那天的股票并且在股价为5的时候卖出,获得收益 5-1 = 4
  3. 股价为3的那天,我们可以看到对比昨天股价5是跌的,所以我们不在股价为5的那天买入股票
  4. 股价为4的那天,我们可以看到对比昨天股价3是涨的,所以我们要买股价为3的那天的股票并且在股价为4的时候卖出,获取收益 4-3 = 1
  5. 股价为6的那天,我们可以看到对比昨天股价4是涨的,所以我们要买股价为4的那天的股票并且在股价为6的时候卖出,获取收益 6-4 = 2

这时候就可以发现,其实步骤3到步骤5这一步,跟我在股价为3的时候买入,股价为6的时候卖出的收益是一样的,因为我们在股价为4的时候卖出了这只股票,然后我们通过开天眼(现实当然不可能),预测到这只股票还会继续涨,所以我们在股价为4的时候卖出又买回了这只股票,这时候我们是没有收益损失的

所以我们只要一直买上涨的股票,就能获得最大收益,也就是这个贪心算法的核心思想。

后来看了下别人的题解,感觉其实这个跟小偷问题有点像,又重新了写了一遍dp的写法

int maxProfit(vector<int>& prices) {
    int n = prices.size();
    int temp = INT_MAX;
    if(n<1) return 0;
    int dp[n][2];
    // dp[i][0] 表示第i天不持有股票的收益,dp[i][1] 表示第i天持有股票的收益
    //(注意,是持有股票,不一定是持有当前的股票,也可能是持有昨天所持有的股票!)
    dp[0][0]=0; 
    dp[0][1]=-prices[0];
    for(int i=1;i<n;i++){
        dp[i][0]=max(dp[i-1][0],dp[i-1][1]+prices[i]);
        dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i]);
    }
    return dp[n-1][0];
}

对于某一天来说,有四种状态

  1. 前一天持有股票,今天卖出
dp[i][0]=dp[i-1][1]+prices[i]

2. 前一天持有股票,今天不操作

dp[i][1]=dp[i-1][1]

3. 前一天不持有股票,今天买入

dp[i][1]=dp[i-1][0]-prices[i]

4. 前一天不持有股票,今天不操作

dp[i][0]=dp[i-1][0]

把这四种状态捋清,思路就很明确了。

End:突然想起写博客只是为了记录下自己学习的过程,笔者是算法小白,正在努力学习算法,希望各位大佬看到了能轻点喷。