121.买卖股票的最佳时间 I
题目内容
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。
注意你不能在买入股票前卖出股票。
思路
引入两个变量,最小买入价格和最大利润,遍历数组,判断最大和最小值来得到最后的结果。
代码
class Solution:
def maxProfit(self, prices):
""" :type prices: List[int] :rtype: int """
if len(prices)<2:
return 0
min_price = prices[0]
max_profile = 0
for i in prices:
min_price = min(min_price, i)
max_profile = max(max_profile, i - min_price)
return max_profile
122.买卖股票的最佳时间 II
题目
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
思路1
与 I 中的区别是可以进行尽可能多的交易。同样,不能参与多笔交易。
可以使用贪心算法。
低价买入,向后判断,高于前一天的价格即可卖出。之后将这一天的价格买入,继续向后判断。
代码
class Solution:
def maxProfit(self, prices):
""" :type prices: List[int] :rtype: int """
if len(prices)<2:
return 0
min_price = prices[0]
max_profile = 0
for i in prices:
if i > min_price:
max_profile = max_profile + i - min_price
min_price = i
return max_profile
思路2
要进行尽可能多的交易,则可以判断相邻两天的股票价格,如果为差值为正,那么就可以将差值累加,得到最后的利润。
代码
class Solution:
def maxProfit(self, prices):
""" :type prices: List[int] :rtype: int """
if len(prices) < 2:
return 0
price = prices[0]
profile = 0
for i in range(1, len(prices)):
profile = profile + max(prices[i]-prices[i-1], 0)
return profile
123.买卖股票的最佳时间 III
题目
给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。
注意: 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
思路1
可以想到,这是121题的扩展,所以可以想到将数组分为前后两部分,前一部分的最大值加上后一部分的最大值即为整体的最大值。但是,将数组分为前后两部分的方式有许多种,还需要判断哪一种分割方式得到的才是最大值。
在做题过程中,简单的运用分割方式的话,出现超时的问题,所以进行了改进,得到可行的代码,代码如下:
代码(超时)
class Solution:
def maxProfit(self, prices):
""" :type prices: List[int] :rtype: int """
if len(prices) < 2:
return 0
m = 1
max_profile3 = prices
while(True):
min_price = prices[0]
max_profile = 0
for i in range(m):
min_price = min(min_price, prices[i])
max_profile = max(max_profile, prices[i]-min_price)
min_price = prices[m-1]
max_profile2 = 0
for j in range(m-1,len(prices)):
min_price = min(min_price,prices[j])
max_profile2= max(prices[j]-min_price, max_profile2)
max_profile3.append(max_profile + max_profile2)
if m == len(prices):
break
m = m + 1
return max(max_profile3)
在这段代码中,一个循环下,还有两个循环,代码复杂度过高,所以考虑精简算法。这段代码将最后的结果都写入max_profile3的数列中。所以,可以考虑,分别定义两个数组,将前半段的最大值和后半段的最大值分别写入两个数组,将整体的最大值的判断写入一个循环,三个循环串行,复杂度减小。
代码(修改)
class Solution:
def maxProfit(self, prices):
""" :type prices: List[int] :rtype: int """
if len(prices) < 2:
return 0
profile1 = [0 for i in range(len(prices))]
profile2 = [0 for i in range(len(prices))]
max_profile = 0
min_price = prices[0]
max_price = prices[len(prices)-1]
for i in range(len(prices)):
min_price = min(min_price, prices[i])
profile1[i] = max(profile1[i-1], prices[i]-min_price)
for j in range(len(prices)-1,-1,-1):
max_price = max(max_price, prices[j])
profile2[j] = max(profile2[j-1], max_price-prices[j])
for i in range(len(prices)):
max_profile = max(max_profile, profile1[i]+profile2[i])
return max_profile
之后还看到有大神的解法,使用动态规划的思想,只需10行左右的代码,这部分将在下一篇中进行分享。