手撕版

最大堆的完全实现, 堆中元素为二元组(num, idx),比较时用数值,赋值或交换时用整个元组。

class Heap:
def __init__(self, arr, capacity):
# 容量和大小
self.size = len(arr)
self.arr = [None] * capacity
self.arr[0] = (10e5, 0)
for i, num in enumerate(arr):
self.arr[i+1] = num def heapify(self, parent):
x = self.arr[parent]
while parent * 2 <= self.size:
child = parent * 2
if child != self.size and self.arr[child + 1][0] > self.arr[child][0]:
child += 1
if self.arr[child][0] > x[0]:
self.arr[parent] = self.arr[child] # 孩子节点值上移
parent = child
else:
break
self.arr[parent] = x def insert(self, item):
self.size += 1
child = self.size # 空穴位置
while item[0] > self.arr[child // 2][0]:
parent = child // 2
self.arr[child] = self.arr[parent]
child = parent
self.arr[child] = item def pop(self):
max_item = self.arr[1] # 取堆顶
self.arr[1] = self.arr[self.size] # 取堆末尾元素
self.size -= 1
self.heapify(1)
# print(self.arr)
return max_item

利用最大堆实现滑动窗口最大值。

创建一个初始大小为K的最大堆,然后向右移动逐个添加元素,同时根据元素索引判断堆顶元素是否在滑动窗口内,若不再则出堆直到在范围内。

class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
if k == 1 or len(nums) == 1:
return nums
else:
res = []
n = len(nums)
# 构造元组形式输入
arr = [(nums[j], j + 1) for j in range(k)] h = Heap(arr, n+1)
for j in range(k // 2, 0, -1):
h.heapify(j) res.append(h.arr[1][0]) for i in range(k, n):
h.insert((nums[i], i + 1))
# i - k + 1为元素索引从1开始的堆
while h.arr[1][1] <= (i - k + 1):
h.pop()
res.append(h.arr[1][0]) return res

不看之前的代码,完全靠手撕最大堆有点费劲。除了上述实现,其实还可以每次向右滑动时,先删除之前K个元素的第一个,然后继续添加元素,再取堆顶。不过手撕起来比较复杂。

调包版

如果面试官允许,可以调包...

heapq的heapify、heappush和heappop

class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
if k == 1 or len(nums) == 1:
return nums
else:
import heapq
arr = [(-nums[j], j + 1) for j in range(k)]
heapq.heapify(arr)
res = [-arr[0][0]] for i in range(k, len(nums)):
heapq.heappush(arr, (-nums[i], i + 1))
# i - k + 1为元素索引从1开始的堆
while arr[0][1] <= (i - k + 1):
heapq.heappop(arr)
res.append(-arr[0][0]) return res

【刷题】LeetCode 239 滑动窗口最大值- Python手撕最大堆的更多相关文章

  1. leetcode 239. 滑动窗口最大值(python)

    1. 题目描述 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最大值. 示 ...

  2. 代码随想录算法训练营day12 | leetcode 239. 滑动窗口最大值 347.前 K 个高频元素

    基础知识 ArrayDeque deque = new ArrayDeque(); /* offerFirst(E e) 在数组前面添加元素,并返回是否添加成功 offerLast(E e) 在数组后 ...

  3. Java实现 LeetCode 239 滑动窗口最大值

    239. 滑动窗口最大值 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最 ...

  4. Leetcode 239.滑动窗口最大值

    滑动窗口最大值 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口 k 内的数字.滑动窗口每次只向右移动一位. 返回滑动窗口最大值. 示例: ...

  5. 【leetcode 239. 滑动窗口最大值】解题报告

    思路:滑动窗口的思想,只要是求连续子序列或者子串问题,都可用滑动窗口的思想 方法一: vector<int> maxSlidingWindow(vector<int>& ...

  6. 代码随想录第十三天 | 150. 逆波兰表达式求值、239. 滑动窗口最大值、347.前 K 个高频元素

    第一题150. 逆波兰表达式求值 根据 逆波兰表示法,求表达式的值. 有效的算符包括 +.-.*./ .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 注意 两个整数之间的除法只保留整数部分. ...

  7. 【leetcode】239. 滑动窗口最大值

    目录 题目 题解 三种解法 "单调队列"解法 新增.获取最大值 删除 代码 题目 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以 ...

  8. LeetCode(239.滑动窗口的最大值

    题目: 给定一个数组nums,有一个大小为k的滑动窗口从数组的最左侧移动到最右侧,你只可以看到滑动窗口内的k个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最大值. 示例: 输入: nums = ...

  9. 【每日一题】【双端降序队列Deque】2021年12月28日-239. 滑动窗口最大值

    给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最大值. 来源:力扣(L ...

  10. LeetCode刷题感想之滑动窗口

    发现滑动窗口也是一种经典解题思路,这一篇简单聊一下滑动窗口. 通常在碰到求XX子数组,子字符串,连续XX等题眼,可以考试用滑动窗口的思路来解决问题. 窗口的类型有几种: 1. 固定长度的窗口. 2. ...

随机推荐

  1. 会话跟踪技术之COOKIE

    会话跟踪技术之COOKIE 一.为什么要用会话控制 我们需要我们的站点可以跟踪客户端与服务器之间的交互,保存和记忆每个用户的身份和信息. 几个疑问 我先访问A页面后访问B页面,HTTP无法知道是不是同 ...

  2. FDMemTable用法

    procedure TForm1.FormCreate(Sender: TObject); Var i:integer; begin // i:=15; self.FDMemTable1.FieldD ...

  3. 如何使用graalvm为带有反射功能的java代码生成native image

    译自Configure Native Image with the Tracing Agent graal官方文档 , 以下所有命令需要在linux环境下操作,graalvm也支持windows. 要 ...

  4. Pandas处理股票数据

    import tushare as ts import pandas as pd # 下载茅台所有股票交易数据 # df = ts.get_k_data(code="600519" ...

  5. 看似简单的input框输入竟然异常卡顿,记一个日常性能问题的排查思路

    壹 ❀ 引 我们公司产品主要提供企业项目管理服务,那么自然有配套的desk工单管理系统,用于搜集客户bug以及相关问题反馈.有一天我在测试功能时碰巧发现了一个bug,所以就想着提一个工单记录下方便日后 ...

  6. NC223888 红色和紫色.md

    题目链接 题目 题目描述 漫长的生命总是无聊的.这天,小红和紫准备玩一个染色游戏. 她们拿出了一个有 \(n*m\) 个格子的网格,每个格子只能被染成红色或紫色.每个人可以任意选择一个格子染成红色和紫 ...

  7. 48.DRF版本控制

    版本控制 版本控制是前后端分离开发一个非常重要的内容,比如说我们重要服务修改.升级等发生版本变化v1.v2.v3等,但是版本发生了变化比如 v1升级到了v2版本,v1版本还有业务在继续使用,相当于同时 ...

  8. Centos7和Centos8的NFS配置

    Centos7和Centos8的NFS配置几乎是完全一样的 服务端 Centos7默认安装了rpcbind, nfs-utils, 其中rpcbind的服务默认是启用的, nfs-utils默认是禁用 ...

  9. pyhotn3.8 apt机器基础镜像构建

    FROM python:3.8.10-slim RUN sed -i 's/deb.debian.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/source ...

  10. 【Android 逆向】【攻防世界】RememberOther

    1. apk安装到手机,提示输入用户名注册码 2. jadx 打开apk public boolean checkSN(String userName, String sn) { try { if ( ...