121. 买卖股票的最佳时机(leetcode)
https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/
经典股票题,此题有贪心做法
class Solution {
public int maxProfit(int[] prices) {
int res = 0;
int minPrice = prices[0];
// 由于只有一次买卖,只需要知道左侧的最小价格和右侧的最大价格即可
// 从左往右遍历,遍历途中维护最小的价格 与 最大现金,每遍历一个数就更新最小价格和最大现金
// 这样就是保证了价格一定在左侧,而卖出的时候一定在右侧,这样是按序遍历的,先买后卖,符合题意
for (int p : prices)
{
res = Math.max(res, p - minPrice);
minPrice = Math.min(minPrice, p);
}
return res;
}
}
class Solution {
public int maxProfit(int[] prices) {
// 由于股票有当前持有还是不持有两个状态,与每天的最大利润,因此有两个维度
// f[i][j]表示在第i天进行选择时的最大现金,j=0,则意味着持有股票,j=1则意味着不持有
// 以第i天是否持有股票划分两个子集,f[i][0]和f[i][1]
// f[i][0]=max(f[i-1][0],-prices[i]) // 以第i-1天是否持有股票划分子集
// -prices[i]意味着此前不持有股票,第i天才买入,由于只买卖一次股票,此前是无现金的
// 因此不需要f[i-1][1]-prices[i],无现金直接就0-prices[i]
// f[i][1]=max(f[i-1][0]+prices[i],f[i-1][1])
// f[0][0]=f[0][1]=0;
// f[1][1]=-price[0],f[1][1]=0 // 初值,这里需要偏移
int[][] f=new int[prices.length+1][2];
f[1][0]=-prices[0];
for(int i=2;i<=prices.length;i++)
{
// 以下prices都需要偏移一位,因为f[i]是从1才开始有意义
f[i][0]=Math.max(f[i-1][0],-prices[i-1]);
f[i][1]=Math.max(f[i-1][0]+prices[i-1],f[i-1][1]);
}
return f[prices.length][1];
}
}

浙公网安备 33010602011771号