题目1
假设有一个数组,它的第i个元素是一支给定的股票在第i天的价格。如果你最多只允许完成一次买入和卖出,设计一个算法来找出最大利润。
样例
给出一个数组样例 [3,2,3,1,2], 返回 1
def maxProfit(self, prices):
# write your code here
n=len(prices)
if n==0:
return 0
profit=0
lowest=prices[0]
for i in range(1,n):
profit=max(prices[i]-lowest,profit)
lowest=min(prices[i],lowest)
return profit
思路:
只关注历史最低值lowest,在这个点买入,如果今后的某个点prices[i]买入使得profit比之前最大的profit大,那就更新profit。
也就是说不仅要有最小值点,后面还要有一个点使得profit比之前最大的profit大
问题2
假设有一个数组,它的第i个元素是一个给定的股票在第i天的价格。设计一个算法来找到最大的利润。你可以完成尽可能多的交易(多次买卖股票)。然而,你不能同时参与多个交易(你必须在再次购买前出售股票)。
def maxProfit(self, prices):
# write your code here
n=len(prices)
if n==0:
return 0
profit=0
total=0
for i in range(n-1):
if prices[i+1]>prices[i]:
profit=prices[i+1]-prices[i]
total=total+profit
return total
思路:
只要相对于前一天有增量,就选择卖出,虽然此时卖出并不是利润最大化的最优解,但是通过累积的增量,比如[1,2,3], 2-1 + 3-2 和3-1的结果是一样的 !
问题3
假设你有一个数组,它的第i个元素是一支给定的股票在第i天的价格。设计一个算法来找到最大的利润。你最多可以完成两笔交易。
样例
给出一个样例数组 [6,1,1,4,2,5], 返回 6
def maxProfit(self, prices):
# write your code here
n=len(prices)
if n==0 or n==1:
return 0
profit=0
left_lowest=prices[0]
left_profit=[0]*n
for i in range(1,n):
profit=max(profit,prices[i]-left_lowest)
left_lowest=min(left_lowest,prices[i])
left_profit[i]=profit
print('left_profit',profit)
print('left_lowest',left_lowest)
profit=0
right_profit=[0]*n
right_highest=prices[n-1]
for i in range(n-2,-1,-1):
profit=min(profit,prices[i]-right_highest)
right_highest=max(right_highest,prices[i])
right_profit[i]=-profit
print('right_profit',profit)
final_profit=0
for i in range(n):
final_profit=max(final_profit,left_profit[i]+right_profit[i])
#differnt from max subarray, buy and sell can occur on same day
print('final_profit',final_profit)
return final_profit
思路:
思路就是扫描线算法,求两个最大不重叠子数组和的思路是一样的,只是这里,可以重叠一个元素(在同一天卖出再买入)。
从左往右的时候记录最小值点,从右往左的时候记录最大值点,另外,从右往左计算的是最小利润,因为是个负值,比如[1,2,4,2,5], 左往右是4-1=3;而右往左是2-5=-3;当然也可以换一种方式写这段代码,不是问题。