力扣解题-121. 买卖股票的最佳时机

5 阅读4分钟

力扣解题-121. 买卖股票的最佳时机

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。

示例 1:

输入:[7,1,5,3,6,4]

输出:5

解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。 注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。

示例 2:

输入:prices = [7,6,4,3,1]

输出:0

解释:在这种情况下, 没有交易完成, 所以最大利润为 0。

提示:

1 <= prices.length <= 105

0 <= prices[i] <= 104


第一次解答

解题思路

核心方法:贪心策略 + 快慢双指针(一次遍历),通过维护“当前最低买入价”和“当前最大利润”两个变量,单次遍历数组即可找到最优解,时间复杂度O(n)、空间复杂度O(1),是本题的最优解法。

核心原理铺垫

股票买卖的核心逻辑:要获取最大利润,需在最低点买入、之后的最高点卖出。利用一次遍历即可实时更新“最低买入价”和“最大利润”,无需嵌套遍历(避免O(n²)的低效):

  • left(慢指针/最低买入价):记录遍历过程中遇到的最低股票价格,初始为第一天的价格(prices[0]);
  • right(快指针/遍历指针):从第二天开始遍历,计算当前价格与left的差值(即当前利润),并更新最大利润;
  • max:记录遍历过程中出现的最大利润,初始为0(无利润时返回0)。
具体步骤
  1. 初始化核心变量
    • left = prices[0]:初始买入价为第一天的价格;
    • max = 0:初始最大利润为0(默认无利润)。
  2. 遍历数组计算利润
    • 快指针right从1开始遍历数组(第二天及以后);
    • 若当前价格prices[right] > left(当前卖出可获利):
      • 计算临时利润temp = prices[right] - left
      • 若临时利润大于当前max,更新max为该临时利润;
    • 若当前价格prices[right] <= left(当前价格更低,更适合买入):
      • 更新leftprices[right](将买入价更新为当前更低的价格);
  3. 返回结果:遍历完成后返回max,若全程无利润则返回初始值0。
核心优化逻辑说明
  1. 时间复杂度最优:仅一次遍历数组(O(n)),每个元素仅被访问一次,无嵌套循环或冗余计算,因此耗时1ms击败100%用户;
  2. 空间复杂度极致:仅使用三个基础变量(left、max、right),空间复杂度O(1),完全符合最优解要求;
  3. 贪心策略的精准适配:每一步都选择“当前最优”(更新最低买入价、更新最大利润),最终得到全局最优解,完美契合“只能一次买卖”的题目规则;
  4. 内存表现说明:内存消耗92.8MB仅击败15.21%用户,并非逻辑问题,而是评测机环境差异(如JVM内存分配、数组存储的内存占用等),该解法的内存开销已达到理论最优。
public int maxProfit(int[] prices) {
        int left=prices[0];
        int max=0;
        for(int right=1;right<prices.length;right++){
            if(prices[right]>left){
                int temp=prices[right]-left;
                if(temp>max){
                    max=temp;
                }
            }else {
                left=prices[right];
            }
        }
        return max;
    }

总结

  1. 该解法的核心是贪心策略的应用:无需记录所有价格组合,仅通过一次遍历维护“最低买入价”和“最大利润”两个核心变量,即可得到最优解;
  2. 关键技巧:
    • 遍历过程中优先更新“最低买入价”,再计算当前利润,确保买入价始终是“当前遍历位置之前的最低价”;
    • 初始最大利润设为0,天然处理“无利润可赚”的场景,无需额外判断;
  3. 性能优势:时间复杂度O(n)适配题目10⁵级别的数据规模,是该问题的理论最优解。