给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
如果你最多只允许完成一笔交易(即买入和卖出一支股票一次),设计一个算法来计算你所能获取的最大利润。
注意:你不能在买入股票前卖出股票。
我思路:本质就是求最大段差(大于0),中间元素可以忽略,只看段的两个端点
1.分治
每次分为左右两段,中间元素两边都要用。用一个全局变量result存储过程中的最大
【如果跨越中间的怎么办?】【未能执行,每次输出都是0,应该是全局变量result没有进入局部】
class Solution(object):
def maxProfit(self, prices):
left=len(prices)-1
result=0
right=0
self.findm(left,right,prices)
return result
def findm(self,left,right,nums):
mid=(len(nums)-1)/2
if right-left>0:
result=max(result,right-left)
if mid!=(left+right)/2:#先判断一下会不会更新#如在[0,1]处 mid不更新永远为0,会陷入死循环 #若不更新则终止递归
mid=(left+right)/2
lm=self.findm(left,mid,prices)
rm=self.findm(mid,right,prices)
2.栈
官方:
走一步看一步,在每个位置处看与历史最小值的差值(即利润),并用historymin维护当前的历史最小值(不是全局最小值)(就不用每次都遍历了)
class Solution:
def maxProfit(self, prices):
inf=int(1e9)
historymin=inf
profit=0
for i in range(len(prices)):#一边往前走,一边看当前值与维护的历史最小值之间的差值
profit=max(profit,prices[i]-historymin)
historymin=min(historymin,prices[i])
return profit
大佬:
class Solution:
def maxProfit(self, prices):
st=[]#单调栈
profit=0
prices.append(0)#哨兵,为在最后将栈中所有元素都弹出来,把栈里的元素也做个比较
for i in prices:
while st and i<st[-1]:#若当前元素小于栈里的一批元素,则弹出他们
x=st.pop()
if st:#弹出以后可能已经为空,而while在下次才能比较
profit=max(x-st[0],profit)
st.append(i)
return profit