股票的最大利润
假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?
示例 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)
- 遍历所有时间,得到最大利润
- 定义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 协议 ,转载请注明出处!