股票的最大利润

假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?

示例 1:

输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
     注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。

示例 2:

输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0

限制:

0 <= 数组长度 <= 10^5

解题思路:

  • 迭代模拟

    要求获利最大,那么自然的思路就是:在买入的时候我们每次都选择价格最小的时间,作为买入时间。然后在买入的每一天都卖出去,求利润进行比较,选最大的利润

    • 定义mini,表示买入的价格 mini = min(mini,prices[i])
    • 定义res,表示利润 res = max(res,prices[i]-mini)
    • 遍历所有时间,得到最大利润
  • AC代码
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int dp[prices.size()];
        int mini = INT_MAX,res = 0;
        for(int i = 0;i < prices.size();i++)
        {
            mini = min(mini,prices[i]);
            res  = max(res,prices[i]-mini);
        }
        return res;
    }
};
  • 动态规划

    定义动态规划之前,要注意两个点

    • 定义什么数组来表示各个阶段的状态
    • 如何得到递推方程
  • 这里我们定义dp[n] [2] 表示前n个阶段的状态

    dp[i] [0] 表示前 i 天,没有持有股票状态下的最大利润

    • 转移方程: dp[i][0] = max(dp[i-1][0],dp[i-1][1]+prices[i])

    dp[i] [1] 表示前 i 天,持有股票状态下的最大利润

    • 转移方程:dp[i][1] = max(dp[i-1][1],0-prices[i])

    注意到上方的转移方程,本来应该是 dp[i-1][0]-prices[i],但是题目要求股票只能买卖一次,0表示未进行股票交易的初始金额,所以如果用 dp[i-1] [0]就代表可能在i-1天完成了多次股票交易,与题意不符

  • AC代码

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

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

构建乘积数组 Previous
圆圈中最后剩下的数字 Next