买卖股票的最佳时机

题目介绍

力扣121题:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/
给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

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

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。
在这里插入图片描述

分析

最简单的想法是,直接找到最大最小值。但最小值可能在最大值之后出现,不符合题目要求。所以我们应该先确定买入点(低点),再考虑之后的卖出点(高点)。

方法一:暴力法

首先可以想到暴力解法:直接遍历每一个价格,作为买入点;再遍历它之后的每一个价格,作为卖出点,取差价最大值即可。

代码如下:

// 方法一:暴力法
public int maxProfit1(int[] prices){
    int maxProfit = 0;
    // 遍历所有可能的买入卖出情况
    for (int i = 0; i < prices.length - 1; i++){
        for (int j = i; j < prices.length; j ++){
            int currProfit = prices[j] - prices[i];
            maxProfit = Math.max(maxProfit, currProfit);
        }
    }
    return maxProfit;
}

复杂度分析

  • 时间复杂度:O(n^2)。双重for循环,耗费平方时间复杂度。
  • 空间复杂度:O(1)。只用了常数个临时变量,没有额外的内存占用。

方法二:动态规划

我们发现,只要在卖出时才能真正确定利润;而要想获取最大利润,就一定要在之前的“历史最低点”买入。所以我们可以以每一天为阶段,确定到目前为止的最优策略,并不断更新。很明显,这就是动态规划的思路。

具体策略是:遍历数组,以当天价格卖出,如果大于之前的最大利润,则更新;而最优的买入点,应该是到目前为止的历史最低价格。每天的价格可能会影响到目前为止的历史最低价格。所以我们其实只需要保存历史最低价格以及目前可能的最大利润。

代码如下:

// 方法二:动态规划
public int maxProfit(int[] prices){
    // 定义状态:保存到目前为止的最小价格,和最大利润
    int minPrice = Integer.MAX_VALUE;
    int maxProfit = 0;

    // 遍历数组元素,以当前价格作为卖出点进行比较
    for (int i = 0; i < prices.length; i ++){
        minPrice = Math.min(minPrice, prices[i]);
        maxProfit = Math.max(maxProfit, prices[i] - minPrice);
    }
    return maxProfit;
}

复杂度分析

  • 时间复杂度:O(n),只有一重循环,遍历一次数组。
  • 空间复杂度:O(1),只用了常数个临时变量,没有额外的内存占用。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值