20. 有效的括号,394.字符串解码,739.每日温度,84. 柱状图中最大的矩形
20. 有效的括号
思路:
- 使用栈来进行消消乐。
- 当是左括号时,则推入栈。
- 如果是右括号,先判断其是否与栈顶元素的左括号匹配,如果匹配的话,那么证明这两个括号构成一对,因此弹出栈顶元素。如果不匹配,则推入栈中。
- 最后检查栈的长度,如果是空栈则证明这些括号是匹配的,否则则证明存在不匹配的部分。
Code
class Solution:def isValid(self, s: str) -> bool:map = {'}': '{',')': '(',']': '[',}stack = []for ele in s:if not stack:stack.append(ele)else:stack_top = stack[-1]if ele in map and map[ele] == stack_top:stack.pop()else:stack.append(ele)if len(stack) == 0:return Trueelse:return False
394.字符串解码
思路
- 根据编码的格式 k [ encoded_string ] 的形式设计栈
- 具体地,遍历字符串每个元素,当元素不是“]”时则统一推入栈中;而当遇到“]”时,此时需要将encoded_string的元素弹出,并还原为原来的encoded_string, 实现完毕后,就将"["弹出。
- 后续,就需要获得k的大小了,k的获取需要判断当前栈顶元素是否为数字,char.isdigit() 方法判断字符是否只包含数字字符(0-9)。
- 在得到数字后,decoded_string = int(k) * encoded_string,此时再将decoded_string推入栈中,因为其在后续可能还需要解码。
- 最后,将stack的元素进行连接就可以得到完全解码后的字符串。
Code
class Solution:def decodeString(self, s: str) -> str:### k [ encoded_string ] 的格式map = { "]", "[",}stack = []for ele in s:if ele != "]":stack.append(ele)else:encoded_string = ""while stack and stack[-1] != "[": ## 当栈顶是"["时,此时已经收集完 encoded_stringencoded_string = stack.pop() + encoded_string ### 插入的字母在头部插入,这样的话就能还原出原字符串stack.pop() ## 弹出 "["num_str = ""decoded_str = ""while stack and stack[-1].isdigit(): ## isdigit() 判断字符串是否只包含数字字符(0-9)num_str = stack.pop() + num_str ## 取出数字decoded_str = int(num_str) * encoded_stringstack.append(decoded_str) ## 解码后再推入return "".join(stack)
739.每日温度
思路:
参考博客:
https://blog.csdn.net/weixin_59234335/article/details/149812733?fromshare=blogdetail&sharetype=blogdetail&sharerId=149812733&sharerefer=PC&sharesource=weixin_59234335&sharefrom=from_link
- 需要注意的是当到了75这个温度后,后面栈是如何计算的
在计算75下一个更高温度出现在几天后前需要先计算栈顶部分的元素,符合栈先入后出的思想,先推入的后计算。
Code
class Solution:def dailyTemperatures(self, temperatures: List[int]) -> List[int]:length = len(temperatures)days_list = [0] * lengthstack = []for cur_idx in range(length):while stack:pre_idx = stack[-1]if temperatures[cur_idx] > temperatures[pre_idx]: #### 实现的是一个单调递增栈,栈顶到栈底是单调递增的days_list[pre_idx] = cur_idx - pre_idxstack.pop() ### 找到了比pre_idx温度高的,那么pre_idx可以弹出去了else:breakstack.append(cur_idx)return days_list
84.柱状图中最大的矩形
思路
参考博客https://blog.csdn.net/weixin_59234335/article/details/149860445?fromshare=blogdetail&sharetype=blogdetail&sharerId=149860445&sharerefer=PC&sharesource=weixin_59234335&sharefrom=from_link
Code
class Solution:def largestRectangleArea(self, heights: List[int]) -> int:heights = [0] + heights + [0] ### 解决边界问题length = len(heights)max_result = [0] * length ### 记录以第index柱形图为高的所能形成的最大矩形面积stack = []sub_stack = []for right in range(length):if not stack:stack.append(right)else:mid = stack[-1]if heights[right] >= heights[mid]: ### 实现的是一个单调递减栈,栈底是最小stack.append(right)else: ### heights[right] < heights[mid] 此时右边柱状图高度比左边柱状图高度低;那right就找到了while stack and heights[right] < heights[stack[-1]]: ### 此时要用while循环实现所有 mid > right的情况,如果是if的话只会实现计算一个mid = stack.pop()cur_high = heights[mid]while stack and heights[stack[-1]] >= cur_high: ### 找到比mid左边比mid小的元素的下标stack.pop()left = stack[-1]##max_result[mid] = cur_high * (right - left - 1)stack.append(right)return max(max_result)