【刷题】LeetCode 239 滑动窗口最大值- Python手撕最大堆
手撕版
最大堆的完全实现, 堆中元素为二元组(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手撕最大堆的更多相关文章
- leetcode 239. 滑动窗口最大值(python)
1. 题目描述 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最大值. 示 ...
- 代码随想录算法训练营day12 | leetcode 239. 滑动窗口最大值 347.前 K 个高频元素
基础知识 ArrayDeque deque = new ArrayDeque(); /* offerFirst(E e) 在数组前面添加元素,并返回是否添加成功 offerLast(E e) 在数组后 ...
- Java实现 LeetCode 239 滑动窗口最大值
239. 滑动窗口最大值 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最 ...
- Leetcode 239.滑动窗口最大值
滑动窗口最大值 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口 k 内的数字.滑动窗口每次只向右移动一位. 返回滑动窗口最大值. 示例: ...
- 【leetcode 239. 滑动窗口最大值】解题报告
思路:滑动窗口的思想,只要是求连续子序列或者子串问题,都可用滑动窗口的思想 方法一: vector<int> maxSlidingWindow(vector<int>& ...
- 代码随想录第十三天 | 150. 逆波兰表达式求值、239. 滑动窗口最大值、347.前 K 个高频元素
第一题150. 逆波兰表达式求值 根据 逆波兰表示法,求表达式的值. 有效的算符包括 +.-.*./ .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 注意 两个整数之间的除法只保留整数部分. ...
- 【leetcode】239. 滑动窗口最大值
目录 题目 题解 三种解法 "单调队列"解法 新增.获取最大值 删除 代码 题目 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以 ...
- LeetCode(239.滑动窗口的最大值
题目: 给定一个数组nums,有一个大小为k的滑动窗口从数组的最左侧移动到最右侧,你只可以看到滑动窗口内的k个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最大值. 示例: 输入: nums = ...
- 【每日一题】【双端降序队列Deque】2021年12月28日-239. 滑动窗口最大值
给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最大值. 来源:力扣(L ...
- LeetCode刷题感想之滑动窗口
发现滑动窗口也是一种经典解题思路,这一篇简单聊一下滑动窗口. 通常在碰到求XX子数组,子字符串,连续XX等题眼,可以考试用滑动窗口的思路来解决问题. 窗口的类型有几种: 1. 固定长度的窗口. 2. ...
随机推荐
- PE格式:新建节并插入DLL
首先老样子,我们先来到PE节表位置处,并仿写一个.hack的节,该节大小为0x1000字节,在仿写前我们需要先来计算出.hack的虚拟偏移与实际偏移,先来查询一下当前节表结构,如下: 接着我们通过公式 ...
- 解决线程不安全的方式(Java)
一.同步代码块 package com.synchronized1; // 买票示例 // 使用同步代码块解决线程安全问题 public class TicketRunnableImp impleme ...
- Worktile团队协作平台介绍
目前很多的基于SaaS模式的云平台都能满足你的需求,同类产品有很多,国内的明道.Worktile.http://Tower.im等,国外的Asana.Trello.Basecamp等,Trello是好 ...
- 小知识:TFA收集日志报错空间不足
今天在某客户环境下分析某节点驱逐的故障,发现有安装TFA,所以使用一键收集包含故障时刻的日志 tfactl diagcollect -from "2020-08-14 03:00:00&qu ...
- 24.1 SetUnhandledExceptionFilter未处理异常--《Windows核心编程》
对于未处理异常,例如异常过滤返回EXCEPTION_CONTINUE_SEARCH,向上搜索,但无法搜索到处理部分,产生未处理异常.Windows提供了 SetUnhandledExceptionFi ...
- JS Leetcode 155. 最小栈 题解分析
壹 ❀ 引 本题来自LeetCode155. 最小栈,难度简单,题目描述如下: 设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈. push(x) -- 将元素 x ...
- 关于php redis的geocoding函数
在php的redis扩展官方github上,文档的最下面的确存在geocoding的函数说明.但是笔者尝试调用geoAdd函数时,返回值一直为false.就纳闷了,是使用的姿势不对,还是存在其它问题? ...
- Java设计模式-组合模式Composite
介绍 组合模式(Composite Pattern),又叫部分整体模式,它创建了对象组的树形结构,将对象组合成树状结构以表示"整体-部分"的层次关系. 组合模式依据树形结构来组合对 ...
- PLSQL编译存储过程无响应
解决方法如下: 1:查V$DB_OBJECT_CACHE SELECT * FROM V$DB_OBJECT_CACHE WHERE name='CRM_LASTCHGINFO_DAY' AND LO ...
- DFS算法模板(2488:A Knight's Journey)
DFS算法(C++版本) 题目一: 链接:http://bailian.openjudge.cn/practice/2488/ 解析思路: 骑士找路就是基本的DFS,用递归不断找到合适的路,找不到就回 ...