算法day 13|239,347

news/2025/1/15 17:25:08/

今日内容:

  • 239. 滑动窗口最大值
  • 347.前 K 个高频元素
  • 总结

239. 滑动窗口最大值 (一刷至少需要理解思路

class Myqueue(object):def __init__(self):self.queue = deque()#保留队列最大的元素在队列里面,其他都pop掉def push(self,value):while len(self.queue)!=0 and value > self.queue[-1]:self.queue.pop()self.queue.append(value)def pop(self,value):if len(self.queue)!=0 and self.queue[0] == value:self.queue.popleft()#获取即将出队的元素def getMax(self):return self.queue[0]class Solution(object):def maxSlidingWindow(self, nums, k):que = Myqueue()result = []for i in range(k):que.push(nums[i])result.append(que.getMax())for i in range(k,len(nums)):que.pop(nums[i-k])que.push(nums[i])result.append(que.getMax())return result

重点:

如何求窗口的最大值:使用队列。这个队列需要实现三个功能:pop(),push(),getmax()。

不能使用堆,这是因为经过排序后,不知道pop出来的元素是什么。

保存的一直都是三个数中最大的数!!

题目链接/文章讲解/视频讲解:代码随想录

二刷:

未ac

def push(self,value):while len(self.que)!=0 and value > self.que[-1]:self.que.pop()self.que.append(value)

我写的是

def push(self,value):while len(self.que)!=0 and value > self.que[0]:self.que.popleft()self.que.append(value)

就是入口处会不会比他小,小的话pop出去。因为可能第一个数(出口处)跟他一样大。那他不就不push出去了,所以得从入口处开始一个一个pop出去

pop()的话是stack中的用法,pop出去的是入口处的元素

popleft()是出口处的元素

三刷

var maxSlidingWindow = function(nums, k) {class MyQueue{constructor(){this.que = []}myPush(value){let back = this.que[this.que.length-1]while(back!==undefined && back<value){this.que.pop()back = this.que[this.que.length-1]}this.que.push(value)}myPop(value){if(this.que.length && value === this.getMaxValue()){// 弹出第一个元素this.que.shift()}}getMaxValue(){return this.que[0]}}let myque = new MyQueue()for(let i = 0;i<k;i++){myque.myPush(nums[i])}let result = []result.push(myque.getMaxValue())let slow = 0let fast = kwhile(slow < fast && fast< nums.length){myque.myPop(nums[slow])myque.myPush(nums[fast])result.push(myque.getMaxValue())slow ++fast ++}return result
};

347.前 K 个高频元素 

class Solution(object):def topKFrequent(self, nums, k):""":type nums: List[int]:type k: int:rtype: List[int]"""import heapqhashmap = {}result = []#使用最大堆minheap = []heapq.heapify(minheap)#将nums存入哈希表中,Python中自带的堆heapq,不支持自定义的比较函数,但是可以自己创建自定义函数for num in nums:hashmap[num] = hashmap.get(num,0)+1#遍历hashmapfor key,fre in hashmap.items():heapq.heappush(minheap,(fre,key))if len(minheap) > k:heapq.heappop(minheap)while len(minheap)!=0:temp = heapq.heappop(minheap)result.append(temp[1])return result

重点

  • 如何求频率:map:key 是num,value是count
  • 如何排序:使用大小堆顶,多适合求前k个高频或者低频的元素
  • 如何使用python自带的堆的比较函数

整体比较简单。就是不知道如何比较这个频率的值

比较函数:__lt__对应<,当对象之间用<比较大小的时候,就会调用__lt__方法。同样的>会调用__gt__方法,在只重写了__lt__方法的时候,__gt__会对__lt__结果取反。但是当比较相等的时候,二者的结果是相等的。

class  P():def __init__(self,a,b):self.a = aself.b = bdef __lt__(self, other):if self.b<other.b:return Trueelse:return False
————————————————
版权声明:本文为CSDN博主「七月听雪」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_23262411/article/details/104854417

题目链接/文章讲解/视频讲解:代码随想录

二刷:

未ac

class Solution:def topKFrequent(self, nums: List[int], k: int) -> List[int]:#统计出现频率,key为num,get(key)为频率hashmap = {}for num in nums:hashmap[num] = hashmap.get(num,0)+1#对频率进行排序import heapqminheap = []heapq.heapify(minheap)for key,fre in hashmap.items():heapq.heappush(minheap,[fre,key])#如果超过k个,就pop出来if len(minheap)>k:heapq.heappop(minheap)print(minheap)result = []#循环遍历一下,将key指加入到结果集中for heap in minheap:result.append(heap[1])return result

三刷

 // 实现一个小顶堆
class Heap {constructor() {this.heap = [];}add(value) {this.heap.push(value);// 获取当前加入值的下标this.heapUp(this.heap.length - 1);}poll() {// 如果 heap 中没有元素if (this.heap.length === 0) {return null;}// 如果 heap 中有一个元素if (this.heap.length === 1) {return this.heap.pop();}// 如果 heap 中有两个及以上元素const item = this.heap[0];this.heap[0] = this.heap.pop();this.heapify(0);return item;}// 将一个元素移动到堆中正确的位置heapUp(index) {// 我们需要计算在父节点的位置const parentIndex = Math.floor((index - 1) / 2);if (parentIndex >=0 && parentIndex < this.heap.length && this.heap[parentIndex][1] > this.heap[index][1]) {this.swap(parentIndex, index);this.heapUp(parentIndex);}}// 需要判断左右孩子,是否比当前元素小heapify(index) {let leftIndex = index * 2 + 1;let rightIndex = index * 2 + 2;let curIndex = index;if (leftIndex < this.heap.length && this.heap[leftIndex][1] < this.heap[curIndex][1]) {curIndex = leftIndex;}if (rightIndex < this.heap.length && this.heap[rightIndex][1] < this.heap[curIndex][1]) {curIndex = rightIndex;}if (curIndex !== index) {this.swap(index, curIndex);this.heapify(curIndex);}}swap(index1, index2) {[this.heap[index1], this.heap[index2]] = [this.heap[index2], this.heap[index1]];}
}
var topKFrequent = function(nums, k) {//将频率存入map中let map = new Map()for (let i = 0; i < nums.length; i++) {map.set(nums[i], (map.get(nums[i]) || 0) + 1)}//建立堆结构let heap = new Heap();for (let [num, count] of map) {heap.add([num, count]);console.log(heap)if (heap.heap.length > k) {heap.poll();}}
}// 将堆中的元素输出
var topKFrequent = function(nums, k) {//将频率存入map中let map = new Map();for (let i = 0; i < nums.length; i++) {map.set(nums[i], (map.get(nums[i]) || 0) + 1);}//建立堆结构let heap = new Heap();for (let [num, count] of map) {heap.add([num, count]);if (heap.heap.length > k) {heap.poll();}}// 取出堆中的元素const result = [];while (heap.heap.length) {result.unshift(heap.poll()[0]);}return result;
};

unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度。

注意: 该方法将改变数组的数目。


http://www.ppmy.cn/news/551934.html

相关文章

【C++核心】函数的应用和提高详解

一. 函数 1.1 概述 作用&#xff1a; 将一段经常使用的代码封装起来&#xff0c;减少重复代码。一个较大的程序&#xff0c;一般分为若干个程序块&#xff0c;每个模块实现特定的功能。 1.2 函数的定义 函数的定义一般主要有5个步骤&#xff1a; 1、返回值类型 2、函数名 3…

从零开始理解Linux中断架构(7)--- Linux执行上下文之中断上下文

1 中断处理程序的基本要求 当前运行的loop是一条执行流,中断程序运行开启了另外一条执行流,从上一节得知这是三种跳转的第三类,这个是一个大跳转。对中断程序的基本要求就是中断执行完毕后要恢复到原来执行的程序,除了时间流逝外,原来运行的程序应该毫无感知。 具体到Armv…

【工具】Spring 历史官方文档理解(持续更新)

文章目录 [1] Spring Framework 5.2.24CoreAOP 概念AspectJoin pointAdvicePointcutIntroductionTarget objectAOP proxyWeaving Spring AOPAspectJ官方 demo 学习 Pointcut 表达式官方 demo 学习 Advice 声明官方 demo 学习 Introductions &#xff08;接口拓展&#xff09;AO…

5.2.3目录与文件之权限意义

现在我们知道了Linux系统内文件的三种身份&#xff08;拥有者、群组与其他人&#xff09;&#xff0c;知道每种身份都有三种权限&#xff08;rwx&#xff09;&#xff0c; 已知道能够使用chown, chgrp, chmod去修改这些权限与属性&#xff0c;当然&#xff0c;利用ls -l去观察文…

C语言倒计时器

今天用这几天所学知识自己编写一个简易计时器&#xff08;因为过于简单&#xff0c;所以不过多解释&#xff09; #include<stdio.h> #include<Windows.h>//编写一个倒计时器void main() {system("title 倒计时器");//设置标题system("mode con col…

51单片机实现倒计时,按键控制倒计时

基于AT89C52的答辩倒计时。四个按键分别控制倒计时开始&#xff0c;暂停&#xff0c;时间加和减。剩下30S时蜂鸣器响&#xff0c;倒计时结束蜂鸣器响。 #include <REGX52.H>unsigned char min1; unsigned char sec00; sbit KEY1P3^1; sbit KEY2P3^0; sbit KEY3P3^2; sbit…

单片机课设-60秒倒计时器

proteus单片机实现60秒倒计时器 项目要实现的60s秒表倒计时器&#xff0c;用 AT89C51单片机的定时 / 计数器 T0 产生一秒的定时时间&#xff0c;实现 59 到 0秒的循环显示的功能。具体要求&#xff1a; 1&#xff09;按下启动按键后&#xff0c;倒计时器开始工作&#xff0c;从…

基于51单片机的倒计时系统

具体实现功能 系统由STC89C52单片机按键电路复位电路晶振电路LCD1602显示模块构成。 具体功能&#xff1a; &#xff08;1&#xff09;六位LED显示&#xff0c;从59分59秒99开始倒计时&#xff1b; &#xff08;2&#xff09;倒计时精度为0.01秒&#xff0c;能正确地进行倒…