首页 > 试题广场 >

买卖股票的最好时机(三)

[编程题]买卖股票的最好时机(三)
  • 热度指数:37568 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
假设你有一个数组prices,长度为n,其中prices[i]是某只股票在第i天的价格,请根据这个价格数组,返回买卖股票能获得的最大收益
1. 你最多可以对该股票有两笔交易操作,一笔交易代表着一次买入与一次卖出,但是再次购买前必须卖出之前的股票
2. 如果不能获取收益,请返回0
3. 假设买入卖出均无手续费

数据范围:,股票的价格满足
要求: 空间复杂度 ,时间复杂度
进阶:空间复杂度 ,时间复杂度
示例1

输入

[8,9,3,5,1,3]

输出

4

说明

第三天(股票价格=3)买进,第四天(股票价格=5)卖出,收益为2
第五天(股票价格=1)买进,第六天(股票价格=3)卖出,收益为2
总收益为4。              
示例2

输入

[9,8,4,1]

输出

0
示例3

输入

[1,2,8,3,8]

输出

12

说明

第一笔股票交易在第一天买进,第三天卖出;第二笔股票交易在第四天买进,第五天卖出;总收益为12。
因最多只可以同时持有一只股票,所以不能在第一天进行第一笔股票交易的买进操作,又在第二天进行第二笔股票交易的买进操作(此时第一笔股票交易还没卖出),最后两笔股票交易同时在第三天卖出,也即以上操作不满足题目要求。        

备注:
总天数不大于200000。保证股票每一天的价格在[1,100]范围内。
贪心算法,和股票买卖一类似,只是要考虑是否第二次买的判断
class Solution:
    def maxProfit(self , prices: List[int]) -> int:
        # write code here
        res = 0 
        n = len(prices)
        b1, b2 = prices[0], prices[0]
        s1, s2 = 0, 0
        for i in range(1, n):
            b1 = min(b1, prices[i])
            s1 = max(s1, prices[i] - b1)
            b2 = min(b2, prices[i] - s1)
            s2 = max(s2, prices[i] - b2)
        return s2


发表于 2022-09-12 21:04:12 回复(0)
class Solution:
    def maxProfit(self , prices: List[int]) -> int:
        # write code here
        
        dp=[0,0,0,0,0]
#         dp[0]  --无股,交易0次
#         dp[1]  --无股,交易1次
#         dp[2]  --无股,交易2次
#         dp[3]  --有股,交易1次
#         dp[4]  --有股,交易2次
        
        
        for i in range(len(prices)):
            if i==0:
                dp[0],dp[1],dp[2]=0,0,0
                dp[3],dp[4] = -prices[i],-prices[i]
                
            else:
                a=[0,0,0,0,0]
                a[0]=dp[0]
                a[1]=max(dp[1],dp[3]+prices[i])
                a[2]=max(dp[2],dp[4]+prices[i])
                a[3]=max(dp[3],dp[0]-prices[i])
                a[4]=max(dp[4],dp[1]-prices[i])
                
                dp=a
        return max(dp)
发表于 2022-08-27 18:01:11 回复(0)

到第i天为止的5种状态:

  • dp[i][0]表示到第i天为止没有买过股票的最大收益
  • dp[i][1]dp[i][1]dp[i][1]表示到第i天为止买过一次股票还没有卖出的最大收益
  • dp[i][2]dp[i][2]dp[i][2]表示到第i天为止买过一次也卖出过一次股票的最大收益
  • dp[i][3]dp[i][3]dp[i][3]表示到第i天为止买过两次只卖出过一次股票的最大收益
  • dp[i][4]dp[i][4]dp[i][4]表示到第i天为止买过两次同时也买出过两次股票的最大收益
    收益可能为负数,可能交易二次的收益大,也可能交易一次收益最大
    class Solution:
      def maxProfit(self , prices: List[int]) -> int:
          res = 0
          n = len(prices)
          dp = [[-10000]*5 for i in range(n)]
          dp[0][0] = 0
          dp[0][1] = -prices[0]
          for i in range(1, n):
              dp[i][0] = dp[i-1][0]
              dp[i][1] = max(dp[i-1][0]-prices[i], dp[i-1][1])
              dp[i][2] = max(dp[i-1][2], dp[i-1][1]+prices[i])
              dp[i][3] = max(dp[i-1][3], dp[i-1][2]-prices[i])
              dp[i][4] = max(dp[i-1][4], dp[i-1][3]+prices[i])
          return max(dp[n-1][2], dp[n-1][4], 0)
发表于 2022-06-24 11:32:44 回复(1)
友友们请教下:为啥dp[i][0] = dp[i-1][0]而不是
dp[i][0] = max(dp[i-1][1]+prices[i],dp[i-1][0])
发表于 2022-06-09 21:43:11 回复(1)
class Solution:
    def maxProfit(self , prices: List[int]) -> int:
        # write code here
        length=len(prices)
        if length==0:
            return 0
        dp=[0]*5
        dp[1]=-prices[0]
        dp[3]=-prices[0]
        for i in range(1,len(prices)):
            dp[1]=max(dp[1],dp[0]-prices[i])
            dp[2]=max(dp[2],dp[1]+prices[i])
            dp[3]=max(dp[3],dp[2]-prices[i])
            dp[4]=max(dp[4],dp[3]+prices[i])
        return dp[4]

发表于 2022-03-24 20:27:20 回复(0)
class Solution:
    def maxProfit(self , prices: List[int]) -> int:
        if len(prices)==0:
            return 0
        firstbuy =prices[0]
        secondbuy=prices[0]
        profit1=0
        profit2=0
        for i in range(len(prices)):
            firstbuy = min(firstbuy,prices[i]);
            profit1 = max(profit1,prices[i]-firstbuy)

            secondbuy = min(secondbuy,prices[i]-profit1)
            profit2 = max(profit2,prices[i]-secondbuy)

        return profit2
发表于 2022-03-17 16:47:17 回复(0)
class Solution:
    def maxProfit(self , prices ):
        # write code here
        if not prices:
            return 0
        buy1 = buy2 = -prices[0]
        sell1 = sell2 = 0
        for i in range(1, len(prices)):
            buy1 = max(buy1, -prices[i])
            sell1 = max(sell1, prices[i] + buy1)
            buy2 = max(buy2, sell1 - prices[i])
            sell2 = max(sell2, prices[i] + buy2)
        return sell2
    # 动态规划最初的理解代码————————————————————————————————
#         if len(prices) <= 1:
#             return 0
#         n = len(prices)
#         dp = [[[0] * 2 for _ in range(3)] for _ in range(n) ] 
#         for k in range(3): # 3表示三个状态,分别是rest, sell, buy
#             dp[0][k][1] = -prices[0] # 第0天时,持有的股票收益都是-prices[0]
#         for i in range(1, n): # i表示天数
#             for k in range(1, 3): # k表示次数
#                 dp[i][k][0] = max(dp[i-1][k][0], dp[i-1][k][1] + prices[i])#0表示没有持有股票,那就要加上今天的prices
#                 dp[i][k][1] = max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i])
#         return dp[n-1][2][0] # n-1表示最后一天,2表示两次交易,0表示手中没有股票

发表于 2021-10-27 20:22:38 回复(0)
class Solution:
    def maxProfit(self , prices ):
        # write code here
        if not prices: return 0
        buy1 = -prices[0]
        buy2 = -prices[0]
        sell1, sell2 = 0, 0
        for i in range(1, len(prices)):
            buy1 = max(buy1, -prices[i])
            sell1 = max(sell1, buy1+prices[i])
            buy2 = max(buy2, sell1-prices[i])
            sell2 = max(sell2, buy2+prices[i])
        return sell2

发表于 2021-08-06 10:43:18 回复(1)
dp1[i]表示第i天及之前卖出可以获得的最大收益
dp2[i]表示第I天及之后买入可以获得的最大收益
最后遍历, 计算max(dp1[k] + dp2[k+1]) 即最大收益

class Solution:
    def maxProfit(self , prices ):
        # write code here
        if prices == []:
            return 0
        dp1 = [0] * len(prices)       # 第i天卖出获得的最大收益
        dp2 = [0] * len(prices)        # 第i天买入获得的最大收益
        min_prices = prices[0]
        profile = 0
        max_prices = prices[-1]
        for i in range(1, len(prices)):
            if prices[i] - min_prices > profile:
                profile = prices[i] - min_prices
            dp1[i] = profile
            if prices[i] < min_prices:
                min_prices = prices[i]
        profile = 0
        for i in range(len(prices)-2, -1, -1):
            if max_prices-prices[i] > profile:
                profile = max_prices-prices[i]
            dp2[i] = profile
            if prices[i] > max_prices:
                max_prices = prices[i]
        max_profile = 0
        for k in range(len(prices)-1):
            if dp1[k] + dp2[k+1] > max_profile:
                max_profile = dp1[k] + dp2[k+1]
        return max_profile
发表于 2021-08-02 14:58:59 回复(1)