手撕版

最大堆的完全实现, 堆中元素为二元组(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. Rsync+Inotify 实现数据同步

    Rsync 是UNIX及类UNIX-Like平台下一款强大的数据镜像备份软件,它不像FTP或其他文件传输服务那样需要进行全备份,Rsync 可以根据数据的变化进行差异备份,从而减少数据流量,提高工作效 ...

  2. (转)时代的见证:集成更新的Windows 7旗舰版、专业版镜像

    制作缘起:微软曾于2019年提供过两份内部集成更新的英文旗舰版.专业版镜像(参见:集成IE11+最新补丁:微软新版Windows 7镜像泄露),方便用户安装,缩短更新过程.经我们下载安装研究发现,这两 ...

  3. Git企业开发控制理论和实操-从入门到深入(一)|为什么需要Git|Git的安装

    前言 那么这里博主先安利一些干货满满的专栏了! 首先是博主的高质量博客的汇总,这个专栏里面的博客,都是博主最最用心写的一部分,干货满满,希望对大家有帮助. 高质量博客汇总https://blog.cs ...

  4. 双端队列(deque)--python

    Python中的双端队列(deque)是一种特殊的数据结构,它允许在队列的两端进行插入和删除操作12.双端队列可以看成栈和队列的结合3.在Python中,我们可以使用collections模块中的de ...

  5. NC24263 USACO 2018 Feb G]Directory Traversal

    题目链接 题目 题目描述 奶牛Bessie令人惊讶地精通计算机.她在牛棚的电脑里用一组文件夹储存了她所有珍贵的文件,比如: bessie/ folder1/ file1 folder2/ file2 ...

  6. nginx 剔除请求参数 $args 变量中任意指定参数之万金油

    剔除任意指定参数配置 只需要修改需要剔除的参数key(如:redirectUrl) #剔除$args中的redirectUrl 参数 server { listen 80; server_name w ...

  7. 优先队列(PriorityQueue)常用方法及简单案例

    1 前言 PriorityQueue是一种特殊的队列,满足队列的"队尾进.队头出"条件,但是每次插入或删除元素后,都对队列进行调整,使得队列始终构成最小堆(或最大堆).具体调整如下 ...

  8. React中的纯组件

    React中的纯组件 React提供了一种基于浅比较模式来确定是否应该重新渲染组件的类React.PureComponent,通常只需要继承React.PureComponent就可以定义一个纯组件. ...

  9. fastjson反序列化各版本利用汇总

  10. pep8相关规范

    https://www.jianshu.com/p/ffcc66bab3ce 导包规范: 1.首先是标准库,如 import os 2.然后是第三方库,如 from django.conf impor ...