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。

思路:选择某一天买入,然后再从这一天之和的某一天卖出,并且卖出的价格一定要大于买入的价格,因此利润最小设置为0,然后遍历prices数组,假设当天买入,然后在今天之后的某一天选择价格最高的那天卖出,得到一个利润,和已有的profit比较,直到遍历完数组。

代码(Python):

class Solution(object):
    def maxProfit(self, prices):
        profit = 0                              #最大利润
        for i in range(len(prices)):
            buyPrice = prices[i]                    #买入价格
            sellPrice = max(prices[i:len(prices)])   #从剩余几天选择一天价格最高的卖出
            profit = max(profit,sellPrice-buyPrice)  #更新profit
        return profit

更新:上述的方法是最直观的,但时间复杂度很高,下面再给出贪心和动规的方法 

贪心:遍历数组,每次都从左边取最小,作为买入的那天,然后计算卖掉能获得的最大利润,和上面的思路一样,但写法不同,时间复杂度也更小一些。 

class Solution(object):
    def maxProfit(self, prices):
        result = 0
        low = 100001
        for i in range(len(prices)):
            low = min(low,prices[i])          #最低买入价格
            result = max(result,prices[i]-low)   #能获得的最大利润
        return result

动态规划:股票问题也是很经典的动规问题。

首先明确定义:dp[i][0]表示第i天持有股票所得的最大利润,dp[i][1]表示第i天不持有股票获得的最大利润;

然后递推公式:首先是dp[i][0]的,第i天持有股票可以分两种情况:1. 第i-1天就持有股票了,那dp[i][0] = dp[i-1][0],2.第i-1天没有股票,在第i天买入了股票,那dp[i][0] = -prices[i],一开始拥有的钱视为0,就等于减去买这支股票的钱。接下去是dp[i][1]的,第i天不持有股票也可以分为两种情况:1.第i-1天也不持有股票,dp[i][1] = dp[i-1][1],2.第i天把股票卖出了,那dp[i][1]=dp[i-1][0]+prices[i],等于前一天持有股票已得的利润加上卖出这支股票的钱。

然后是初始化:每个dp[i]依赖于dp[i-1]的值,因此dp[0][0]和dp[0][1]都需要初始化,dp[0][0]表示第0天持有股票,那就等于-prices[0],dp[0][1]表示第0天不持有股票,那就为0。

最后是遍历顺序,很明显从前往后遍历。

class Solution(object):
    def maxProfit(self, prices):
        dp = [[0]*2 for _ in range(len(prices) )]
        if len(prices) == 0:
            return 0
        dp[0][0] = -prices[0]
        dp[0][1] = 0
        for i in range(1,len(prices)):
            dp[i][0] = max(dp[i-1][0],-prices[i])
            dp[i][1] = max(dp[i-1][1],dp[i-1][0]+prices[i])
        return dp[len(prices)-1][1]
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值