算法记录 | Day13 栈与队列

239. 滑动窗口最大值

思路:

1.设计单调队列

2.pop(value):如果窗口移除的元素value等于单调队列的出口元素,那么队列弹出元素,否则不用任何操作

3.push(value):如果push的元素value大于入口元素的数值,那么就将队列入口的元素弹出,直到push元素的数值小于等于队列入口元素的数值为止

from collections import deque
class MyQueue:
    def __init__(self) -> None:
        self.queue = deque()
    
    def pop(self, value):
        if self.queue and value == self.queue[0]:
            self.queue.popleft()
    
    def push(self, value):
        while self.queue and value > self.queue[-1]:
            self.queue.pop()
        self.queue.append(value)

    def front(self):
        return self.queue[0]

class Solution:
    def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
        que = MyQueue()
        result = []
        for i in range(k):
            que.push(nums[i])
        result.append(que.front())
        for i in range(k,len(nums)):
            que.pop(nums[i-k])
            que.push(nums[i])
            result.append(que.front())
        return result

347.前 K 个高频元素

思路:

1.大顶堆(根节点是最大元素)和小顶堆(根节点是最小元素)

2.小顶堆,pop弹出

class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        num_dict =dict()
        for num in nums:
            if num in num_dict:
                num_dict[num]+=1
            else:
                num_dict[num] = 1

        pri_que = [] #小顶堆
        for key, freq in num_dict.items():
            heapq.heappush(pri_que, (freq, key))
            if len(pri_que)>k:
                heapq.heappop(pri_que)
        res = [0] * k
        for i in range(k-1, -1, -1):
            res[i] = heapq.heappop(pri_que)[1]
        return res

python deque

deque
collections模块常用类型有:
双向队列(deque):类似于list的容器,可以快速的在队列头部和尾部添加、删除元素
计数器(Counter):dict的子类,计算可hash的对象
默认字典(defaultdict):dict的子类,可以调用提供默认值的函数
有序字典(OrderedDict):dict的子类,可以记住元素的添加顺序
可命名元组(namedtuple):可以创建包含名称的tuple

deque

append():从右侧添加元素
appendleft():从左侧添加元素

from collections import deque
queue = deque()
queue.append(1)
queue.append(2)
queue.append(3)
print(queue)         #deque([1, 2, 3])
queue.appendleft(0)
print(queue)         #deque([0, 1, 2, 3])

extend():从右端逐个添加可迭代对象(与list同)Python中的可迭代对象有:列表、元组、字典、字符串
extendleft():从左端逐个添加可迭代对象,Python中的可迭代对象有:列表、元组、字典、字符串

from collections import deque
st = "abcd"
list = [0, 1, 2, 3]
dst = deque(st) 		#deque(['a', 'b', 'c', 'd'])
dst.extend(list)		#deque(['a', 'b', 'c', 'd', 0, 1, 2, 3])
dstl = deque(st)
dstl.extendleft(ex)	    #deque([3, 2, 1, 0, 'a', 'b', 'c', 'd'])
print(dst)
print(dstl)

pop():移除列表中的一个元素(默认最右端的一个元素),并且返回该元素的值(与list同),如果没有元素,将会报出IndexError
popleft():移除列表中的一个元素(默认最左端的一个元素),并且返回该元素的值,如果没有元素,将会报出IndexError
remove():移除第一次出现的元素,如果没有找到,报出ValueError
insert(index,obj)

a = queue.popleft()  #从队首(左边) pop
b = queue.pop()      #从队尾(右边) pop
print(a,b)  # 0 3
print(queue)         #deque([1, 2])

#在指定位置增删
queue.insert(2,3)  #.insert(location, value)
print(queue)       #deque([1, 2, 3])

queue.remove(3)    #.remove(val)
print(queue)       #deque([1, 2])

rotate(n):rotate(n), 从右侧反转n步,如果n为负数,则从左侧反转。d.rotate(1) 等于 d.appendleft(d.pop())
clear():将deque中的元素全部删除,最后长度为0
maxlen:只读的属性,deque限定的最大长度,如果无,就返回None。

python heapq

heapq

1.heappush

import heapq
a = []   

#小堆根
heapq.heappush(a,18)
heapq.heappush(a,1)
heapq.heappush(a,20)
heapq.heappush(a,10)
heapq.heappush(a,5)
heapq.heappush(a,200)
print(a)       					  # [1, 5, 20, 18, 10, 200]

#大堆根
a = []
for i in [1, 5, 20, 18, 10, 200]:
    heapq.heappush(a,-i)
print(list(map(lambda x:-x,a)))   # [200, 18, 20, 1, 10, 5]

def FindMaxProfit(profits, key=lambda x: -x):
    maxHeap1 = []
    for i in range(len(profits)):
        heappush(maxHeap1, (-profits[i], profits[i])) # 大顶堆
        # heappush(maxHeap1, profits[i])  # 默认小顶堆
    return heappop(maxHeap1)

2.heapify

#小堆根

a = [1, 5, 20, 18, 10, 200]
heapq.heapify(a)
print(a)      				# [1, 5, 20, 18, 10, 200]

#大堆根

a = [1, 5, 20, 18, 10, 200]
a = list(map(lambda x:-x,a))
heapq.heapify(a)
print([-x for x in a])      # [200, 18, 20, 5, 10, 1]

3.heappop

heapq.heappop()是从堆中弹出并返回最小的值

3.1 利用heappop进行堆排序

import heapq
def heap_sort(arr):
    if not arr:
        return []
    h = []  #建立空堆
    for i in arr:
        heapq.heappush(h,i) #heappush自动建立小根堆
    return [heapq.heappop(h) for i in range(len(h))]  #heappop每次删除并返回列表中最小的值

3.2 普通list的heapop()

a = [3,6,1]
heapq.heapify(a)
ap = heapq.heappop(a)
print(ap)  # 1

b = [4,2,5]
bp = heapq.heappop(b)
print(bp)  # 4

b = [4,2,5]
heapq.heapify(b)
bp = heapq.heappop(b)
print(bp)  # 2

4.heappushpop(heap,item)

heapq.heappushpop()是heappush和haeppop的结合,同时完成两者的功能,先进行heappush(),再进行heappop()

h = [1,2,9,5]
hp = heapq.heappop(h)
print(hp)   # 1

hp = heapq.heappushpop(h,4)
print(hp)   # 2
print(h)    #[4, 5, 9]

5.heapreplace(heap.item)

弹出并返回 heap 中最小的一项,同时推入新的 item

heapq.heapreplace()与heapq.heappushpop()相反,先进行heappop(),再进行heappush()

a = []
#ap = heapq.heapreplace(a,3)    #list为空报错
heapq.heappush(a,3)
print(a)                        # [a]
ap = heapq.heapreplace(a,2)     # 先执行删除(heappop(a)->3),再执行加入(heappush(a,2))
print(ap)                       # 3
print(a)                        # [2]
a = [2, 4, 9, 5]
ap = heapq.heapreplace(a,6)     # 先从堆a中找出最小值并返回,然后加入6
print(ap)                       # 2
print(a)                        # [4, 5, 9, 6]

6.merge(*iterables)

heapq.merge()合并多个堆然后输出
输入的list无序,merge后无序,若输入的list有序,merge后也有序

# 无序
a = list(heapq.merge([11,33,55,22],[66,99,77,88]))
print(a)       # [11, 33, 55, 22, 66, 99, 77, 88]
# 有序
b = list(heapq.merge([1,33,55],[6,19,27,88]))
print(b)       # [1, 6, 19, 27, 33, 55, 88]

7.nlargest(n , iterbale, key=None) &nsmallest(n , iterbale, key=None)

获取列表中最大、最小的几个值,key的作用和sorted( )方法里面的key类似

a = [0, 1, 2, 3, 4, 5, 5, 7, 8, 10, 15, 20, 25]
al = heapq.nlargest(5,a) 
print(al)                    # [25, 20, 15, 10, 8]
ass = heapq.nsmallest(5,a) 
print(ass)                   # [0, 1, 2, 3, 4]

b = [('a',1),('b',2),('c',3),('d',4),('e',5)]
bl = heapq.nlargest(1,b,key=lambda x:x[1])      
print(bl)                    # [('e', 5)]
bs = heapq.nsmallest(1,b,key=lambda x:x[1])
print(bs)                    # [('a', 1)]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值