当前位置: 首页 > news >正文

Day10,Hot100(栈,堆)

(1)20. 有效的括号

在这里插入图片描述

        d = {')':'(', ']':'[', '}':'{'}
        stack = []
        for i in s:
            # 遇到左括号,入栈
            if i in '([{':
                stack.append(i)
            # 遇到右括号,出栈左括号,看是否有匹配的左括号
            else:
                if not stack:  # 栈空的时候遇到右括号,则一定不能匹配
                    return False
                if d[i] == stack[-1]:  # 右括号与前面的左括号匹配
                    stack.pop()
                else:
                    return False

        if not stack:  # 栈为空, 说明全部都匹配成功
            return True
        return False

(2)155. 最小栈

在这里插入图片描述

维护一个最小栈,存储当前栈的最小值
栈尾总是当前栈的最小值

  • push时需要判断新加入的值是否小于 min_st[-1]
  • pop的时候需要判断pop的元素是否是 min_st[-1]
class MinStack:
    def __init__(self):
        self.stack = []
        self.min_st = []  # 保存stack中的最小值

    def push(self, val: int) -> None:
        self.stack.append(val)
        if not self.min_st or self.min_st[-1] >= val:
            self.min_st.append(val)

    def pop(self) -> None:
        if self.stack.pop() == self.min_st[-1]:
            self.min_st.pop()

    def top(self) -> int:
        return self.stack[-1]

    def getMin(self) -> int:
        return self.min_st[-1]

(3)394. 字符串解码

在这里插入图片描述
在这里插入图片描述

示例:3[a2[c]]

  1. 3[ a2[c] ]
  2. a2[c]
  3. 2[c]

  1. 2[c] --> cc
  2. a2[c] --> acc
  3. 3[ a2[c] ] --> acc acc acc
class Solution:
    def decodeString(self, s: str) -> str:
        stack = []
        res = ''  # 当前解码的字符串
        multi = 0  # 当前的倍数

        for c in s:
            if c == '[':
                stack.append((res, multi))  # 数字之前的结果,以及数字
                multi = 0
                res = ''
            elif '0' <= c <= '9':
                multi = multi * 10 + int(c)
            elif c == ']':
                last_res, cur_multi = stack.pop()
                res = last_res + cur_multi * res
            else:
                res += c
        return res

(4)739. 每日温度

在这里插入图片描述
单调栈

  • 及时去掉无用数据
  • 保证栈中元素有序
    在这里插入图片描述

方法一:从左往右遍历

  • 栈内保留还没有找到答案的元素
  • 当元素大于栈顶时出栈栈顶, 每次在出栈的时候更新答案,

在这里插入图片描述

class Solution:
    def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
        n = len(temperatures)
        ans = [0] * n
        st = []  # 存储数组下标

        for i in range(n):
            t = temperatures[i]
            while st and t > temperatures[st[-1]]:
                j = st.pop()
                ans[j] = i - j
            st.append(i)
        
        return ans

方法二:从右往左遍历

  • 逐步出栈,直到遇到符合条件的温度,更新答案
class Solution:
    def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
        n = len(temperatures)
        ans = [0] * n
        st = []  # 存储数组下标

        for i in range(n-1, -1, -1):
            t = temperatures[i]
            # 如果栈顶元素小于当天温度,则持续出栈,直到找到
            while st and t >= temperatures[st[-1]]:
                st.pop()
            if st:
                ans[i] = st[-1] - i
            st.append(i)

        return ans                   

堆是一颗完全二叉树,即每一层都被完全填满,最后一层从左到右填充

最大堆

  • 父节点 >= 子结点,堆顶为最大值
      10
     /  \
    8    9
   / \  / 
  3  7 4

最小堆

  • 父节点 <= 子结点,堆顶为最小值
      3
     / \
    7   4
   / \ 
  8   9

堆的插入和删除操作的时间复杂度为 O(log n),n为堆的元素个数

heapq 模块默认是 最小堆,要实现最大堆,可以将所有元素取反


(1)215. 数组中的第K个最大元素

在这里插入图片描述

最小堆

  • 维护一个大小为k的最小堆
  • 最终堆顶就是第 k 大的元素
import heapq
class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        min_heap = nums[:k]
        heapq.heapify(min_heap)  # 使用前k个元素构建最小堆

        # 从第 k+1 个元素开始遍历
        for num in nums[k:]:
            if num > min_heap[0]:
                heapq.heappop(min_heap)  # 弹出堆顶元素
                heapq.heappush(min_heap, num)  # 插入新的元素

        return min_heap[0]  # 堆顶元素就是第 K 个最大的元素

最大堆

  • 将整个数组堆化,逐个弹出堆顶
  • 第 k 个堆顶就是第 k 大的元素
import heapq
class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        nums = [-num for num in nums]
        heapq.heapify(nums)

        for _ in range(k):
            res = -heapq.heappop(nums)
        
        return res

(2)347. 前 K 个高频元素

使用 Counter 统计每个元素的频率
使用最小堆,维护一个大小为 k 的频率

heapq.heappush(heap, (count, num))

  • heap中加入元素 (count, num)
  • 最小堆会自动首先按照第一个元素 count 大小排序,构建最小堆
import heapq
from collections import Counter

class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        cnt = Counter(nums)  # 统计词频
        heap = []

        for num, count in cnt.items():
            heapq.heappush(heap, (count, num))

            if len(heap) > k:
                heapq.heappop(heap)
        
        return [num for count, num in heap]

相关文章:

  • 了解状态机
  • C#: 日志函数
  • 新版 WSL2 2.0 设置 Windows 和 WSL 镜像网络教程
  • Linux提权之john破解shadow root密文登录提权(十)
  • 《操作系统 - 清华大学》 8 -7:进程管理:进程挂起
  • 内部知识库的核心模块是什么?
  • libwebsockets交叉编译全流程
  • 【每日八股】Redis篇(一):概述
  • 计算机毕设-基于springboot的汽车配件销售管理系统的设计与实现(附源码+lw+ppt+开题报告)
  • rust学习笔记4-基础类型2和内存管理模型
  • ike-scan:发现并指纹识别 IKE 主机(IPsec VPN 服务器)!全参数详细教程!Kali Linux教程!黑客教程!
  • 解决jupyter notebook不是内部或外部命令问题
  • 正则表达式--捕获exec方法
  • Grouped-Query Attention(GQA)详解: Pytorch实现
  • 红帽7基于kickstart搭建PXE环境
  • 【MySQL 一 数据库基础】深入解析 MySQL 的索引(3)
  • redis-bitmap使用场景
  • CSS中的`position`属性的几种定位方式
  • 计算机视觉算法实战——三维重建(主页有源码)
  • Linux提权之suid提权(六)
  • 中国证券监督管理委员会党委委员、副主席王建军接受审查调查
  • 招商蛇口:一季度营收约204亿元,净利润约4.45亿元
  • 零食连锁鸣鸣很忙递表港交所:去年营收393亿元,门店超1.4万家,净利润率2.1%
  • 黄宾虹诞辰160周年|一次宾翁精品的大集结
  • 牛市早报|今年第二批810亿元超长期特别国债资金下达,支持消费品以旧换新
  • “75后”袁达已任国家发改委秘书长