0
点赞
收藏
分享

微信扫一扫

牛客——堆/栈/队列

敬亭阁主 2022-05-06 阅读 46
python

文章目录

1.用两个栈实现队列

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
栈:先进后出,队列:先进先出

class Solution:
    def __init__(self):
        self.stack1 = []
        self.stack2 = []
    def push(self, node):
        # write code here
        self.stack1.append(node)
        # 插入
    def pop(self):
        # return xx
        if len(self.stack2) == 0:
            while (len(self.stack1) != 0):
                # 把1里边的弹出,依次加入2里边
                self.stack2.append(self.stack1.pop())# .pop 是直接在调用
        value = self.stack2.pop()
        return value

2.包含min函数的栈

在这里插入图片描述
在这里插入图片描述
题都看不懂
在这里插入图片描述

class Solution:
    def __init__(self):
        self.stack=[]
        self.stack_min=[]
        # 这个得看视频 我说不明白 引入了一个辅助栈
    def push(self, node):# 插入
        # write code here
        self.stack.append(node)
        
        if self.stack_min==[]:
            self.stack_min.append(node)
        else:
            val=min(node,self.stack_min[-1])
            self.stack_min.append(val)
    def pop(self):# 弹出
        # write code here
        self.stack.pop()
        self.stack_min.pop()
        
    def top(self):# 栈顶
        # write code here
        return self.stack[-1]
    def min(self):# 最小
        # write code here
        return self.stack_min[-1]

3.有效括号序列

在这里插入图片描述
在这里插入图片描述


一个不正确的方法

class Solution:
    def isValid(self , s: str) -> bool:
        # write code here
        #长度为奇数 一定不对
        if len(s)%2 == 1:
            return False
        #只有3种括号在s中,才进行替换
        while '{}' in s or '[]' in s or '()' in s:
            s = s.replace('[]','').replace('{}','').replace('()','')
        return True if s=='' else False

正确的做法,这个不是顺序做的,而是倒序

class Solution:
    def isValid(self , s: str) -> bool:
        # write code here
        if s == '' or s[-1] == '{' or s[-1] == '[' or s[-1] == '(':
            return False
        stack = []
        for i in reversed(s):
            # reserved() 是 Python 内置函数之一
            # 对于给定的序列(包括列表、元组、字符串以及 range(n) 区间),返回一个逆序序列的迭代器(用于遍历该逆序序列)
            if i == '}' or i == ']' or i == ')':
                stack.append(i)
            else:
                if len(stack) == 0:
                    return False
                if (i == '{' and stack[-1] == '}') or (i == '[' and stack[-1] == ']') or (i == '(' and stack[-1] == ')'):
                    stack.pop(-1)
#         return True if len(stack) == 0 else False
        return len(stack) == 0 

正序

class Solution:
    def isValid(self , s: str) -> bool:
        # write code here
        if s == '' or s[-1] == '{' or s[-1] == '[' or s[-1] == '(':
            return False
        stack = []
        for i in s:
            if i == '{' or i == '[' or i == '(':
                stack.append(i)
            else:
                if len(stack) == 0:
                    return False
                if (i == '}' and stack[-1] == '{') or (i == ']' and stack[-1] == '[') or (i == ')' and stack[-1] == '('):
                    stack.pop(-1)
        return len(stack) == 0 

4.滑动窗口的最大值(数据流)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

# 使用队列
# 数组【2,3,4,2,6,2,5,1】为例,滑动窗口大小为3
# 1、先把第一个数字2加入队列,第二个数字是3,比2大,所以2不可能是最大值,所以把2删除,3存入队列。
# 2、第三个数是4,比3大,同样删3存4,此时滑动窗口以遍历三个数字,最大值4在队列的头部。
# 3、第4个数字是2,比队列中的数字4小,当4滑出去以后,2还是有可能成为最大值的,因此将2加入队列尾部,此时最大值4仍在队列的头部。
# 4、第五个数字是6,队列的数字4和2都比它小,所以删掉4和2,将6存入队列尾部,此时最大值6在队列头部。
# 5、第六个数字是2,此时队列中的数6比2大,所以2以后还有可能是最大值,所以加入队列尾部,此时最大值6在仍然队列头部。
# 依次进行,这样每次的最大值都在队列头部。
# 还有一点需要注意的是:如果后面的数字都比前面的小,那么加入到队列中的数可能超过窗口大小,
# 这时需要判断滑动窗口是否包含队头的这个元素,
# 为了进行这个检查,我们可以在队列中存储数字在数组中的下标,而不是数值,
# 当一个数字的下标和当前出来的数字下标之差大于等于滑动窗口的大小时,这个元素就应该从队列中删除。
class Solution:
    def maxInWindows(self , num: List[int], size: int) -> List[int]:
        # write code here
        queue=[]# 存的是下标
        res=[]# 这个是最后结果
        i=0# i是找的值的左边的下标
        # 整体是属于 不断的加入 不断的弹出这么在搞
        while size>0 and i<len(num):
            if len(queue)>0 and i-size+1>queue[0]:# 存储的下标>0 存储的下标已经不符合要求了 要弹出
                # 每一步都在检验 我现在的下标和存储的下标合不合适
                queue.pop(0)
            while len(queue)>0 and num[queue[-1]]<num[i]:# 当前值比存进去的值大 所以删掉现在这个
                queue.pop()
            queue.append(i)
            # 把符合的下标存入队列
            if i>=size-1:# 把搞定的下标换成数字存入res
            	# 因为每增加一个数就会多一个最大值,所以只要>=size就可以了
                # 需要注意的就是前size个一直不能存
                res.append(num[queue[0]])
            i+=1
        return res

暴力 有一个特别长的肯定是跑不完的

class Solution:
    def maxInWindows(self , num: List[int], size: int) -> List[int]:
        # write code here
        # 暴力 有一个特别长的肯定是跑不完的
        left,n=0,len(num)
        x=[]
        if n==0 or size>n:
            return []
        while left+size<n+1:
            x.append(max(num[left:left+size]))
            left+=1
        return x

5.最小的K个数

在这里插入图片描述
我会用的白痴方法

class Solution:
    def GetLeastNumbers_Solution(self, tinput, k):
        # write code here
        list=[]
        if len(tinput)<k:
            return list
        else:
            tinput.sort()
            return tinput[:k]

在这里插入图片描述
在这里插入图片描述

借助最大最小堆

import heapq
class Solution:
    def GetLeastNumbers_Solution(self , input: List[int], k: int) -> List[int]:
        # write code here
        # 建立新容器 input中的值遍历 比容器最大值小的话 就进行替换
        # 用到了最大堆
        if k==0:
            return []
        # python中只有最小堆 所以就要将所有元素取反 弹出元素的时候也取反
        heap=[-x for x in input[:k]]
        heapq.heapify(heap)# 借助函数将其转换为堆
        for num in input[k:]:
            if -num > heap[0]:
                heapq.heapreplace(heap,-num)# 将heap堆顶的移出 并把-num放进去
        return [-x for x in heap]

6.寻找第K大

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

同样也是借助最大堆
小顶堆+相反数:

import heapq
class Solution:
    def findKth(self , a: List[int], n: int, K: int) -> int:
        # write code here
        heap = []
        for i in range(n):
            heapq.heappush(heap, -a[i]) # 小顶堆存进去负数
        for i in range(K-1):
            heapq.heappop(heap) #出队前K-1个(最大的)
        return -heapq.heappop(heap) # 相反数

快速排序:

class Solution:
    def findKth(self , a: List[int], n: int, K: int) -> int:
         return self.quickSort(a, 0, n-1, K)

    def quickSort(self, a, start, end, k):
        if start>end:
            return -1
        pivot = a[start]
        left,right = start,end
        while left<right: # 和下面的小于号一致
            while left<right and a[right]<=pivot: # 由大到小
                right -= 1
            while left<right and a[left]>=pivot:
                left += 1
            if left!=right:
                a[left],a[right] = a[right],a[left]
        a[left],a[start] = a[start],a[left] # 最后left是比pivot大的
        if left==k-1: # 是序号,第k个
            return a[left]
        elif left<k-1:
            return self.quickSort(a, left+1, end, k)
        else:
            return self.quickSort(a, start, left-1, k)


7.


8.


9.


1.


1.


1.


1.


1.


1.


举报

相关推荐

0 条评论