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];
    }
}

 

posted @ 2024-09-06 00:13  风乐  阅读(21)  评论(0)    收藏  举报