leetcode 122. Best Time to Buy and Sell Stock II 详解 python3

一.问题描述

Say you have an array for which the ith element is the price of a given stock on day i.

Design an algorithm to find the maximum profit. You may complete as many transactions as you like (i.e., buy one and sell one share of the stock multiple times).

Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again).

Example 1:

Input: [7,1,5,3,6,4]
Output: 7
Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4.
             Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3.

Example 2:

Input: [1,2,3,4,5]
Output: 4
Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.
             Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are
             engaging multiple transactions at the same time. You must sell before buying again.

Example 3:

Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.

二.解题思路

一开始我以为这道题挺复杂的,是要把数组分成若干个子数组并且所有子数组中最大值与最小值之差 的和最大。

后面仔细分析题目,发现是我想复杂了。

感觉这道题目主要考的是critical thinking, 你的分析能力。

首先如果是之做一次交易,要求最大收益,那肯定是整个数组的最大值和最小值相减。

但是考虑多次交易的话情况就不一样了,得考虑我们怎么确保所有交易和最大。

怎样确定交易的开始和结束?

设想以下连续的两次交易,是什么原因要我们把交易要分成两次?

假设两次交易的买出和卖出坐标分别是start1,end1,start2,end2。

那么肯定有 prices[start1]<prices[end1]>=prices[start2] and prices[start2]<prices[end2]

prices[end1]>prices[start1]  和 prices[end2]>prices[start2]这是我们的盈利要求,没得说

关键点在于prices[start2]>prices[end1],

考虑如果prices[end1]<prices[start2]的情况,两次交易的关系就是prices[start1]<prices[end1]<prices[start2]<prices[end2],

既然如此,那我为何不在start1买入,end2卖出?合并成一次交易。

也就是说,出现两个规律:

1.两次交易之间,prices[end1~start2]是一个递减的子数列。

2.一次交易之间, prices[start~end]是一个递增的子数列,如果不是,那根据我们之前讨论的,这个交易就可以分割成两个。

更直观一点理解是,你可以想象以下股票不都是波动的折线,把我们的数组话一个散点图,我们向获得最大的利益,

就是在每一段上升的区间中,在最低点买入,再最高点卖出,然后之后开始迭,迭到底我们再买入,重复。如下图:

因此只需要把每一段递增的子序列的end-start 相加就好了。

虽然是一道easy难度的题目,但是如果想不明白这一点的话会非常难。

分析能力才是我们最被考察也最需要掌握的一点,不要一看到题目一上手就巴拉巴拉,多分析以下题目,不然就会像我,写了半个小时之后才发现。

更多leetcode算法题解法: 专栏 leetcode算法从零到结束

三.源码

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        if not prices: return 0
        start,res=0,0
        for i in range(1,len(prices)):
            if prices[i]<prices[i-1]:
                res+=prices[i-1]-prices[start]
                start=i
        if len(prices)>1 and prices[-1]>=prices[-2]:res+=prices[-1]-prices[start]
        return res

#version 2 再进一步理解,既然是一个递增子数列并且要计算头尾差,那就可以一个一个加,不用指针
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        if not prices: return 0
        res=0
        for i in range(1,len(prices)):
            if prices[i]>prices[i-1]:
                res+=prices[i]-prices[i-1]
        return res

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值