题121.买卖股票的最佳时机-简单(一次交易)
题意
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
如果你最多只允许完成一笔交易(即买入和卖出一支股票一次),设计一个算法来计算你所能获取的最大利润。
注意:你不能在买入股票前卖出股票。
输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。
解题思路
本题作为股票买卖系列题目中最简单的一道,解题方法非常直接,就是进行一次遍历,更新两个值:最小买入价 和 最大利润, 直至遍历结束,输出最大利润
- 将最低买入价初始化为无限大,而后逐天比较,更新为更小值
- 因为只能交易一次,所以遍历中拿每天的卖出价和当前最小买入价计算差值,更新最大利润
时间复杂度为O(n)
代码
profit,buy=0,float('inf')
for i in prices:
profit=max(profit,i-buy) #更新最大利润
buy=min(buy,i) #更新最小买入价
return profit
题122.买卖股票的最佳时机-简单(不限次数)
题意
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
解题思路
本题和121题的区别就是 不限次数 ,所以只需要不断地计算当前和前一天的差值就行了,跌了的舍去,涨了的加上。
一:计算每日差值
用tmp存储每天与上一天的股价差值,如果涨了的话,加到profit中。
profit=0
for i in range(len(prices)-1):
tmp=prices[i+1]-prices[i]
profit+=tmp if tmp>0
return profit
二:更新持股与未持股利润
维护一个数组 dp,含两个值,其中
- dp[0] 代表当前未持有股票的利润,每天比较
- 昨日未持股票利润 dp[0]
- 昨日持股今日卖出的利润 dp[1]+price
- dp[1] 代表当前持有股票的利润,每天比较
- 昨日持股利润 dp[1]
- 昨日未持股今日卖入的利润 dp[0]-price
遍历中不断更新这两个值,最终输出最后一天未持股票的利润 dp[0]
dp=[0,-prices[0]]
for i in prices:
dp[0]=max(dp[0],dp[1]+i)
dp[1]=max(dp[1],dp[0]-i)
return dp[0]
题124.二叉树的最大路径和
题意
路径 被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。该路径 至少包含一个 节点,且不一定经过根节点。
路径和 是路径中各节点值的总和。
给你一个二叉树的根节点 root ,返回其 最大路径和 。
eg
输入: root = [1,2,3]
输出: 6
解释: 最优路径是 2 -> 1 -> 3 ,路径和为 2 + 1 + 3 = 6
解题
根据题意,很容易想到递归的方法,我的做法是从底部开始,将所有可能的路的值加到一个数组 res 中,然后输出该数组最大值。
每对一棵树进行计算时,假设左右的子树的返回值分别为 A, B,中间节点的值为m,
- 那么返回上级树的值就是 A+m、B+m 和 m 三个值中的最大值
- 而添加到 res 数组中的则是 A、B、A+m、B+m 和 m 五个值,当然也可先对这五个值进行比较后再添加到res中
具体实现如下:
if not root:
return float('-inf')
res=[]
def helper(root):
res.append(root.val)
if not root.left and not root.right:
return root.val
cur=[]
if root.left:
cur.append(helper(root.left))
if root.right:
cur.append(helper(root.right))
res.append(max(cur)+root.val if root.val>0 else max(cur))
res.append(sum(cur)+root.val)
return max(cur)+root.val if max(cur)>0 else root.val
helper(root)
return max(res)
改进
不用res数组来存储可能的值,直接定义一个tmp值,在每棵树比较得出更大的值,假如当前树返回给上层树的值都为负,或者说上层一定舍弃这个值的话,将返回设为0。
tmp=float('-inf')
def helper(root):
if not root: return 0
left=helper(root.left)
right=helper(root.right)
tmp=max(tmp,root.val+left+right)
return max(max(left,right)+root.val,0)
helper(root)
return tmp