贪心的思路:
得到最小值,再挨个用数组中的值减去最小值,最终值取一个最大的
class Solution {
public:
int maxProfit(vector<int>& prices) {
// 贪心: 找到最小的,然后逐个减掉最小的,取最终值为最大的为 res
int low = INT_MAX;
int res = 0;
for(int i = 0; i < prices.size(); i++)
{
low = min(prices[i], low);
res = max(res, prices[i] - low);
}
return res;
}
};
动规的思路:
现在觉得做动规的关键点就是找出,当前的状态是否与之前的状态有关,也就是说:当前一般会有两种状态,具体哪一种为最优,需要依靠之前的状态及逆行推导。
比如说本题
当天有两种状态:持有股票,和不持有股票。(这里没有使用买入、卖出作为含义是因为:单纯的买入,卖出,无法表示出更确切的状态。比如说前一天买入,后一天不进行任何操作,那么这个不进行操作的状态就无法表示了
1. dp数组的表示含义
这里使用二维数组的原因是因为,一个维度表示天数,一个维度表示股票的状态
dp [ i ] [ 0 ] 表示第 i 天持有股票,值为:所获得的利润
dp [ i ] [ 1 ] 表示第 i 天不持有股票, 值为:所获得的利润
2. 递推公式
持有股票:
第 i 天买入的: -price[ i ]
第 i 天之前就买入了:dp[ i - 1][ 0 ]
两者取最大值
不持有股票:
第 i 天卖出: dp [ i - 1][ 0 ] + price[ i ]
第 i 天之前就卖出了: dp [ i - 1 ][ 1 ]
两者取最大值
3. 初始化
dp[ 0 ] [ 0 ] = - price[ 0 ]
dp[ 0 ] [ 1 ] = 0
4. 遍历顺序,从前向后
注意:
这里最终求的其实就是
dp [ price.size() - 1] [ 1 ]
因为最后一定是手里没有股票的利润会更大
class Solution {
public:
int maxProfit(vector<int>& prices) {
vector<vector<int>> dp(prices.size(), vector<int>(2));
// 初始化
dp[0][0] = -prices[0];
dp[0][1] = 0;
// 遍历 + 递推
for(int i = 1; i < prices.size(); i++)
{
dp[i][0] = max(dp[i - 1][0], -prices[i]);
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);
}
return dp[prices.size() - 1][1];
}
};
3. 双指针文章来源:https://www.toymoban.com/news/detail-432588.html
一个指向前一天,一个指向当天,这样就保证只会在买入后卖出,找出利润最大的文章来源地址https://www.toymoban.com/news/detail-432588.html
class Solution {
public:
int maxProfit(vector<int>& prices) {
// 双指针
int left = 0 ,right = 1;
int res = 0;
for(; right < prices.size();)
{
int x = prices[right] - prices[left];
if(x > 0) // 不断移动 right,继续寻找更大的利润
{
res = max(res, x);
right++;
}
else //如果利润为负数 让 left 尽可能小,然后移动一次right
{
left = right; // 注意这里是直接移动到right , 让 left 处于尽可能小的位置
right++;
}
}
return res;
}
};
到了这里,关于leetcode 121. 买卖股票的最佳时机 (贪心 + 动规的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!