推荐阅读:股票问题系列通解(转载翻译)

为了更好的理解和记忆,这里给出我重新整理后的解法,每个解法都很相似,只需改动少量的条件

121. 买卖股票的最佳时机
1    public int maxProfit(int[] prices) {
2        int buy = -prices[0]; // 第一天买,减去买的价钱
3        int sale = 0; // 第一天卖,不存在这种情况,没有收益
4        for (int price : prices) {
5            buy = Math.max(buy, -price); // 买,减去买的价钱
6            sale = Math.max(sale, buy + price); // 卖,在买的收益基础上加上卖的价钱
7        }
8        return sale;
9    }
122. 买卖股票的最佳时机 II
1    public int maxProfit(int[] prices) {
2        int buy = -prices[0]; // 第一天买,扣掉买的价钱
3        int sale = 0; // 第一天卖,不存在这种情况,没有收益
4        for (int price : prices) {
5            buy = Math.max(buy, sale - price); // 买,在卖的收益基础上减去买的价钱
6            sale = Math.max(sale, buy + price); // 卖,在买的收益基础上加上卖的价钱
7        }
8        return sale;
9    }
123. 买卖股票的最佳时机 III
 1    public int maxProfit(int[] prices) {
 2        int buy1 = -prices[0]; // 第一天买,减去买的价钱
 3        int sale1 = 0; // 第一天卖,不存在这种情况,没有收益
 4        int buy2 = -prices[0]; // 第一天买,减去买的价钱
 5        int sale2 = 0; // 第一天卖,不存在这种情况,没有收益
 6        for (int price : prices) {
 7            buy1 = Math.max(buy1, -price); // 第一次买,减去买的价钱
 8            sale1 = Math.max(sale1, buy1 + price); // 第一次卖,在第一次买的收益基础上加上卖的价钱
 9            buy2 = Math.max(buy2, sale1 - price); // 第二次买,在第一次卖的收益基础上减去买的价钱
10            sale2 = Math.max(sale2, buy2 + price); // 第二次卖,在第二次买的收益基础上加上卖的价钱
11        }
12        return sale2;
13    }
188. 买卖股票的最佳时机 IV

这是六大问题中最难的一个,所对应的解法是最通用的

 1    public int maxProfit(int k, int[] prices) {
 2        int len = prices.length;
 3        if (len <= 1) {
 4            return 0;
 5        }
 6        k = Math.min(k, len / 2); // 买入卖出成对才能形成收益,k 超过天数的一半就没有意义
 7        int[] buy = new int[k + 1];
 8        int[] sale = new int[k + 1];
 9        Arrays.fill(buy, -prices[0]);
10        for (int price : prices) {
11            for (int i = 1; i <= k; i++) {
12                buy[i] = Math.max(buy[i], sale[i - 1] - price); // 买,在上一次卖的收益基础上减去买的价钱
13                sale[i] = Math.max(sale[i], buy[i] + price); // 卖,在买的收益基础上加上卖的价钱
14            }
15        }
16        return sale[k];
17    }
309. 最佳买卖股票时机含冷冻期
 1    public int maxProfit(int[] prices) {
 2        int buy = -prices[0]; // 第一天买,减去买的价钱
 3        int sale = 0; // 第一天卖,不存在这种情况,没有收益
 4        int prevSale = 0; // 记录前一次卖的收益,初始为0
 5        for (int price : prices) {
 6            buy = Math.max(buy, prevSale - price); // 买,在前一次卖的基础上减去买的价钱
 7            prevSale = sale; // 记录前一次卖的收益
 8            sale = Math.max(sale, buy + price); // 卖,在买的基础上加上卖的价钱
 9        }   
10        return sale;
11    }
714. 买卖股票的最佳时机含手续费
1    public int maxProfit(int[] prices, int fee) {
2        int buy = -prices[0]; // 第一天买,减去买的价钱
3        int sale = 0; // 第一天卖,不存在这种情况,没有收益
4        for (int price : prices) {
5            buy = Math.max(buy, sale - price); // 买,在卖的基础上减去买的价钱
6            sale = Math.max(sale, buy + price - fee); // 卖,在买的基础上加上卖的价钱,再扣除手续费
7        }   
8        return sale;
9    }