1、第一题:买卖股票的最佳时机i:
1.1 题目描述:
1.2 实现思路:
维护一个单调递增栈。具体做法如下:
-
1、遍历数组prices,如果栈顶元素小于当前遍历的元素,则当前元素直接入栈;如果栈顶元素大于当前遍历的元素,栈顶元素出栈,直到栈顶元素不大于当前遍历元素为止,这个时候当前元素才能入栈。
-
2、栈顶元素 减 栈底元素,就是当前所遍历到的结果的最优解,记录下来。
-
3、返回结果。
1.3 代码实现:
class Solution:
def maxProfit(self, prices: List[int]) -> int:
stack = []
res = 0 # 记录最大值
for i in range(len(prices)):
while stack:
if prices[i] < stack[-1]: # 当前遍历元素 < 栈顶元素,则出栈
stack.pop()
else:
break
stack.append(prices[i])
if res < stack[-1] - stack[0]:
res = stack[-1] - stack[0]
return res
注意:其实这道题维护一个单调栈有点多余,只需要维护一个最小值就可以,但是因为看到这类题直接能想到的是单调栈解法,感觉到时候面试只能想到单调栈法,因此就把这种解法写下来。
2、第二题:买卖股票的最佳时机ii:
2.1 题目描述:
2.2 实现思路:
依然是维护一个单调栈,和第一道题不一样的地方在于,这道题找的是整个序列里有几个单调递增的子序列。因此,每次将一段子序列入栈,当判断下一个元素不递增时,那就把栈清空,并记录下这个子序列的最大差值;接着进行下一个子序列的判断。
- 1、遍历整个数组,先让第一个子序列都入栈;
- 2、若下一个元素破坏了递增的规则,那么第一个子序列就结束,并记录下第一个子序列的最大差值(加入到结果列表中);
- 3、以后的子序列都和第一个子序列一样的做法;
- 4、最后还要注意,最后一个子序列我们还没有取出来,因此还需要把最后一个子序列的值取出来;
- 5、将结果列表求和,就是最终的结果;
2.3 代码实现:
class Solution:
def maxProfit(self, prices: List[int]) -> int:
res = [] # 存放结果
stack = []
for i in range(len(prices)):
if stack and prices[i] < stack[-1]:
res.append(stack[-1] - stack[0]) # 栈顶 - 栈底
stack.clear()
stack.append(prices[i])
if len(stack) > 1: # 取最后一个子序列
res.append(stack[-1] - stack[0])
return sum(res)