力扣labuladong一刷day10一网打尽股票买卖问题共6题

力扣labuladong一刷day10股票买卖问题共6题

一、121. 买卖股票的最佳时机

题目链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/
思路:只能买入1次,定义dp[i][0]数组表示第i天持有股票时手中的最大金额 数,定义dp[i][1]表示第1天手中不持有股票时手中金额最大值。
这里的持有表示为一种状态,可以是之前就持有的,也可以是今天才持有的。

class Solution {
   public int maxProfit(int[] prices) {
        int[][] dp = new int[prices.length][2];
        dp[0][0] = -prices[0];
        for (int i = 1; i < prices.length; i++) {
            dp[i][0] = Math.max(dp[i-1][0], -prices[i]);
            dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0]+prices[i]);
        }
        return dp[prices.length-1][1];
    }
}
class Solution {
    public int maxProfit(int[] prices) {
        int len = prices.length;
        int[] dp = new int[2];
        dp[0] = -prices[0];
        for (int i = 1; i < prices.length; i++) {
            dp[0] = Math.max(dp[0], -prices[i]);
            dp[1] = Math.max(dp[1], dp[0]+prices[i]);
        }
        return dp[1];
    }
}

二、122. 买卖股票的最佳时机 II

题目链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/
思路:上一题类似,只不过是可以进行无数次交易,本题还可以优化及dp[2]。

class Solution {
    public int maxProfit(int[] prices) {
        int len = prices.length;
        int[][] dp = new int[len][2];
        dp[0][0] = -prices[0];
        for (int i = 1; i < len; i++) {
            dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1]-prices[i]);
            dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0]+prices[i]);
        }
        return dp[len-1][1];
    }
}
class Solution {
   public int maxProfit(int[] prices) {
        int len = prices.length;
        int[] dp = new int[2];
        dp[0] = -prices[0];
        for (int i = 1; i < prices.length; i++) {
            dp[0] = Math.max(dp[0], dp[1]-prices[i]);
            dp[1] = Math.max(dp[1], dp[0]+prices[i]);
        }
        return dp[1];
    }
}

三、123. 买卖股票的最佳时机 III

题目链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iii/
思路:和上一题的区别是最多只能进行两次交易,dp[0]和dp[1]表示第一次交易的持有和不持有状态,dp[2]和dp[3]表示第二次交易的持有和不持有状态。

class Solution {
    public int maxProfit(int[] prices) {
        int len = prices.length;
        int[] dp = new int[4];
        dp[0] = -prices[0];
        dp[2] = -prices[0];
        for (int i = 1; i < len; i++) {
            dp[0] = Math.max(dp[0], -prices[i]);
            dp[1] = Math.max(dp[1], dp[0]+prices[i]);
            dp[2] = Math.max(dp[2], dp[1]-prices[i]);
            dp[3] = Math.max(dp[3], dp[2]+prices[i]);
        }
        return dp[3];
    }
}

四、188. 买卖股票的最佳时机 IV

题目链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iv/
思路:本题与上一题不同之处在与拓展了一下,设置最多可以购买k次,前面是购买两次我们还可以展开写成dp[0]、dp[1]、dp[2]、dp[3],两天就写了4行,要是k天我们无法穷举都写出来,需要借助for循环来进行缩写。其他的没有什么,唯一要注意的就是,交易次数。
dp[i][j+1] = Math.max(dp[i-1][j+1], dp[i-1][j]-prices[i]);
这个是计算持有,如果之前就已经完成了该次交易买入,交易数就是本身,如果之前没进行,是今天才进行该次的买入,那依赖的便是上一次交易的卖出,交易数自然减一。
卖出同样同理。

class Solution {
   public int maxProfit(int k, int[] prices) {
        int len = prices.length, m = 2*k+1;
        int[][] dp = new int[len][m];
        for (int i = 1; i < m; i+=2) {
            dp[0][i] = -prices[0];
        }
        for (int i = 1; i < len; i++) {
            for (int j = 0; j < m-2; j+=2) {
                dp[i][j+1] = Math.max(dp[i-1][j+1], dp[i-1][j]-prices[i]);
                dp[i][j+2] = Math.max(dp[i-1][j+2], dp[i-1][j+1]+prices[i]);
            }
        }
        return dp[len-1][m-1];
    }
}

五、309. 买卖股票的最佳时机含冷冻期

题目链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-with-cooldown/
思路:含有冷静期的,初始化时要注意,冷静期为1天,那么第二天要计算持有,要么是第一天就持有了,要么是第二天才持有,第二天才持有第一天就是冷静期,所以是0-prices[i]。那么如果是冷静期为k天,也可以按照这个思路来处理。
剩下的如果要计算持有都是依赖于2天前的,因为中间有一天冷静期。

class Solution {
    public int maxProfit(int[] prices) {
        int len = prices.length;
        int[][] dp = new int[len][2];
        for (int i = 0; i < len; i++) {
            if (i == 0) {
                dp[i][0] = -prices[0];
                continue;
            }
            if (i == 1) {
                dp[i][0] = Math.max(dp[i-1][0], -prices[i]);
                dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0]+prices[i]);
                continue;
            }
            dp[i][0] = Math.max(dp[i-1][0], dp[i-2][1]-prices[i]);
            dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0]+prices[i]);
        }
        return dp[len-1][1];
    }
}

六、714. 买卖股票的最佳时机含手续费

题目链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/
思路:含有续费的就是在卖出时减掉手续费即可。

class Solution {
    public int maxProfit(int[] prices, int fee) {
        int len = prices.length;
        int[] dp = new int[2];
        dp[0] = -prices[0];
        for (int i = 1; i < len; i++) {
            dp[0] = Math.max(dp[0], dp[1]-prices[i]);
            dp[1] = Math.max(dp[1], dp[0]+prices[i]-fee);
        }
        return dp[1];
    }
}

你可能感兴趣的:(力扣算法题,leetcode,动态规划,股票问题)