手撕版

最大堆的完全实现, 堆中元素为二元组(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. C# 中类与继承等概念

    C#是一种现代的.面向对象的编程语言,其中类和继承是面向对象编程语言中非常重要的概念,类和继承是C#中面向对象编程的基本概念,可以用于创建复杂的应用程序和模块,而多态和接口可以使程序更加灵活和可扩展. ...

  2. Spring一套全通5—SSM整合

    百知教育 - Spring系列课程 - MVC框架整合 第一章.MVC框架整合思想 1. 搭建Web运行环境 <dependency> <groupId>javax.servl ...

  3. (C语言)每日代码||2023.12.24||printf换行的三种方法

    #include <stdio.h> int main() { //printf()函数不同参数间可以换行 printf("num one : %d,num two : %d&q ...

  4. Python中os.walk函数说明

    这个函数对于文件方面的遍历等其他方面的操作来说功能很强大,比如批量修改文件名.批量移动文件.将所有不在一个文件夹下的文件移动到同一个文件夹下等等. 这个其实很简单的,用一个示例就能明白这个函数的具体用 ...

  5. 好书推荐之《Java 核心技术:卷 1 基础知识》

    大佬推荐 <Java 核心技术:卷 1 基础知识>,这本书本来是 Sun 公司的官方用书,是一本 Java 的入门参考书. 对于 Java 初学者来说,是一本非常不错的值得时常翻阅的技术手 ...

  6. USB至串口TTL转接设备及Console线

    USB转串口常见芯片方案 FT232, FTDI(英国) 公认稳定可靠, 传输速率3Mbps, 功能最强, 单芯片内置SPI,TWI,JTAG,GPIO等功能. FT232BM为较早型号, FT232 ...

  7. 基于keras的残差网络

    1 前言 理论上,网络层数越深,拟合效果越好.但是,层数加深也会导致梯度消失或梯度爆炸现象产生.当网络层数已经过深时,深层网络表现为"恒等映射".实践表明,神经网络对残差的学习比对 ...

  8. Js中Array对象

    Js中Array对象 JavaScript的Array对象是用于构造数组的全局对象,数组是类似于列表的高阶对象. 描述 在JavaScript中通常可以使用Array构造器与字面量的方式创建数组. c ...

  9. 配置nginx反向代理

    最近在做一个前后分离的项目,前端用Vue,后台spring boot,使用nginx做反向代理.下面说一下如何配置: 启动spring boot项目,端口8110 启动nginx 修改nginx.co ...

  10. spring boot整合dubbo

    本项目通过模拟卖票和买票模块来讲解spring boot如何整合dubbo. 1.搭建zookeeper 使用docker方式: docker pull registry.docker-cn.com/ ...