leetcode 算法之买卖股票的最佳时机 II

0 阅读3分钟

给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。

在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。然而,你可以在 同一天 多次买卖该股票,但要确保你持有的股票不超过一股。

返回 你能获得的 最大 利润 。

 

示例 1:

输入: prices = [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3。
最大总利润为 4 + 3 = 7

示例 2:

输入: prices = [1,2,3,4,5]
输出: 4
解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4。
最大总利润为 4 。

示例 3:

输入: prices = [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 交易无法获得正利润,所以不参与交易可以获得最大利润,最大利润为 0。

 

提示:

  • 1 <= prices.length <= 3 * 104
  • 0 <= prices[i] <= 104
解题思路

假设股票价格序列:[7, 1, 5, 3, 6, 4]

第1天: 7
第2天: 1  ← 买入
第3天: 5  ← 卖出,利润 = 5-1 = 4
第4天: 3  ← 买入
第5天: 6  ← 卖出,利润 = 6-3 = 3
第6天: 4

我们看到这个提示题目本身是可以多次交易跟我们上一篇讲的是不同 上一个题目是只能交易一次 现在是可以多次交易 本质是贪心算法 只要今天比昨天贵,就昨天买今天卖

具体实现

public int maxProfit(int[] prices) {
    // 边界条件检查
    if (prices == null || prices.length < 2) {
        return 0;
    }

    int profit = 0;
    for (int i = 0; i < prices.length - 1; i++) {  // 注意这里是 length-1
        if (prices[i+1] > prices[i]) {
            profit += prices[i+1] - prices[i];
        }
    }
    return profit;
}

这里要注意边界我们的i要小于 prices.length - 1 不然会数组越界的

  • 测试用例

public static void main(String[] args) {
    Leetcode8 solution = new Leetcode8();

    // 测试用例1:正常递增情况
    int[] prices1 = {1, 2, 3, 4, 5};
    int result1 = solution.maxProfit(prices1);
    System.out.println("测试用例1 - 递增价格: " + java.util.Arrays.toString(prices1));
    System.out.println("预期结果: 4, 实际结果: " + result1);
    System.out.println("测试通过: " + (result1 == 4 ? "✓" : "✗"));
    System.out.println();

    // 测试用例2:混合价格波动
    int[] prices2 = {7, 1, 5, 3, 6, 4};
    int result2 = solution.maxProfit(prices2);
    System.out.println("测试用例2 - 混合价格: " + java.util.Arrays.toString(prices2));
    System.out.println("预期结果: 7, 实际结果: " + result2);
    System.out.println("测试通过: " + (result2 == 7 ? "✓" : "✗"));
    System.out.println();

    // 测试用例3:边界情况
    int[] prices3 = {5};
    int result3 = solution.maxProfit(prices3);
    System.out.println("测试用例3 - 单个元素: " + java.util.Arrays.toString(prices3));
    System.out.println("预期结果: 0, 实际结果: " + result3);
    System.out.println("测试通过: " + (result3 == 0 ? "✓" : "✗"));
    System.out.println();

    // 额外测试:null和空数组
    System.out.println("额外测试 - null数组: " + solution.maxProfit(null));
    System.out.println("额外测试 - 空数组: " + solution.maxProfit(new int[]{}));
}

测试结果

image.png

  • 第二种解法

public  int maxProfit2(int[] prices) {
    if (prices == null || prices.length < 2) {
        return 0;
    }
    int profit = 0;
    for (int i = 1; i < prices.length; i++) {
        if (prices[i] > prices[i-1]) {
            profit += prices[i] - prices[i-1];
        }
    }
    return profit;


}

单元测试

public static void main(String[] args) {
    Leetcode8 solution = new Leetcode8();

    // 测试用例1:正常递增情况
    int[] prices1 = {1, 2, 3, 4, 5};
    int result1 = solution.maxProfit2(prices1);
    System.out.println("测试用例1 - 递增价格: " + java.util.Arrays.toString(prices1));
    System.out.println("预期结果: 4, 实际结果: " + result1);
    System.out.println("测试通过: " + (result1 == 4 ? "✓" : "✗"));
    System.out.println();

    // 测试用例2:混合价格波动
    int[] prices2 = {7, 1, 5, 3, 6, 4};
    int result2 = solution.maxProfit2(prices2);
    System.out.println("测试用例2 - 混合价格: " + java.util.Arrays.toString(prices2));
    System.out.println("预期结果: 7, 实际结果: " + result2);
    System.out.println("测试通过: " + (result2 == 7 ? "✓" : "✗"));
    System.out.println();

    // 测试用例3:边界情况
    int[] prices3 = {5};
    int result3 = solution.maxProfit2(prices3);
    System.out.println("测试用例3 - 单个元素: " + java.util.Arrays.toString(prices3));
    System.out.println("预期结果: 0, 实际结果: " + result3);
    System.out.println("测试通过: " + (result3 == 0 ? "✓" : "✗"));
    System.out.println();

    // 额外测试:null和空数组
    System.out.println("额外测试 - null数组: " + solution.maxProfit2(null));
    System.out.println("额外测试 - 空数组: " + solution.maxProfit2(new int[]{}));
}

测试结果

image.png