Leetcode——买卖股票问题汇总

2023.12.14

        今天二刷到股票问题,遂总结一下leetcode中买卖股票的四种题型:买卖股票的最佳时机 、买卖股票的最佳时机II 、买卖股票的最佳时机III 、买卖股票的最佳时机含手续费 。

        建议按顺序解题,会有循序渐进的感觉。

买卖股票的最佳时机Leetcode——买卖股票问题汇总_第1张图片

         本题需要注意买卖股票不能在同一天,并且只能买卖一次。我们可以使用动态规划来做:首先dp数组设定为一个二维数组:第一个维度的长度代表总天数;第二个维度的长度为2,代表持股或者不持股两种情况。如下图左边所示:

Leetcode——买卖股票问题汇总_第2张图片

        dp[i][0]就代表第 i+1 天不持股的当前金额, dp[i][1]就代表第 i+1 天买入持股的当前金额。所以第一天的金额我们可以进行初始化,也方便后续dp数组进行赋值。由题意可知第一天的股票是7元,那么dp[0][0]就应该初始化为0,dp[0][1]应该初始化为-7。

        递推公式如上图的右边所示。当不持股的时候,当前金额可能是上一阶段不持股的金额,也可能是上一阶段买入股票当前卖出股票剩余的金额,取这两个中较大值作为当前金额。  而当持股的时候,可能是刚买了当天的股票,也可能是之前买的股票没有卖,当前金额取决于这两种情况哪个股票更便宜。 因此递推公式为:

dp[i][0] = Math.max(dp[i-1][0],dp[i-1][1]+prices[i]);

dp[i][1] = Math.max(dp[i-1][1],-prices[i]);

         本题的java代码如下:

class Solution {
    public int maxProfit(int[] prices) {
        int dp[][] = new int[prices.length][2];
        dp[0][0] = 0;
        dp[0][1] = -prices[0];
        for(int i=1; i

买卖股票的最佳时机II

Leetcode——买卖股票问题汇总_第3张图片

        本题相比于上一题,区别仅在于买卖股票的次数从一次变为无数次。 因此,在持股状态下时,有两种可能:①延续之前就已经买了股票的状态:dp[i][1] = dp[i-1][1] ②之前买了股票并且卖掉了,今天又买了股票:dp[i][1] = dp[i-1][0]-prices[i] 。

        上面的②就是与前一题递推公式的区别所在。因为前一题买卖股票次数只能有一次,在持股状态下的两种可能性就是:①延续之前就已经买了股票的状态②今天买了股票。 这里的②不存在之前就买过股票的情况,因为股票只能买卖一次。

        java代码如下:

class Solution {
    public int maxProfit(int[] prices) {
        int dp[][] = new int[prices.length][2];
        dp[0][0] = 0;
        dp[0][1] = -prices[0];
        for(int i=1; i

买卖股票的最佳时机III

Leetcode——买卖股票问题汇总_第4张图片

        弄懂了上面两题之后,这道困难题也就迎刃而解了。 本题与上述题的区别在于:限制买卖股票的次数为2次。 于是,可以定义一个二维数组,第二个维度设置为4,分别代表:第一次持有股票的状态、 第一次持不有股票的状态、第二次持有股票的状态、第二次不持有股票的状态。如下图:

Leetcode——买卖股票问题汇总_第5张图片

        第一次持有股票和不持有股票的递推公式可以类比第一题,第二次持有股票和不持有股票的递推公式可以类比第二题。

        java代码实现如下:

class Solution {
    public int maxProfit(int[] prices) {
        int dp[][] = new int[prices.length][4];
        //初始化
        dp[0][0] = -prices[0];
        dp[0][1] = 0;
        dp[0][2] = -prices[0];
        dp[0][3] = 0;
        for(int i=1; i

买卖股票的最佳时机(含手续费)

Leetcode——买卖股票问题汇总_第6张图片

         本题两个关键点:①可以无限次买卖股票,参考本系列的第二题。②每次卖出股票需要手续费。

        本题和第二题的递推公式的区别在于:卖出股票的时候需要减去手续费,也就是在不持有股票的递推公式有一点点变化。

        java代码实现如下:

class Solution {
    public int maxProfit(int[] prices, int fee) {
        int dp[][] = new int[prices.length][2];
        dp[0][0] = -prices[0];
        dp[0][1] = 0;
        for(int i=1; i

 

你可能感兴趣的:(leetcode专栏,leetcode,算法,股票买卖问题,动态规划,java)