机试打卡 -12 滑动窗口最大值(优先队列&堆)

 


 我的思路1:队列,每次 出队+入队,记录1个队列中的最大值索引,超时。。。

class Solution:
    def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
        
        nums_len=len(nums)

        ans_list=[]
        
        # 队列长度为k
        queue=nums[:k]

        # 队列最大值索引
        max_index=queue.index(max(queue))
        ans_list.append(queue[max_index])

        for i in range(k,nums_len):

            # 出队
            del queue[0]
            max_index-=1

            # 入队
            queue.append(nums[i])

            # 判断队列最大值索引的状态
            # 若最大值索引移出,则重新判断标记最大值索引
            if max_index<0:
                max_index=queue.index(max(queue))

            # 若最大值索引未移出,则比较新进元素和队列标记数的大小
            else:
                if nums[i]>=queue[max_index]:
                    max_index=k-1
                else:
                    pass

            ans_list.append(queue[max_index])
                
        return ans_list

我的思路2:建立排序队列,每次 出队+入队,采用 折半搜索,超时。。。

class Solution:
    def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
        
        nums_len=len(nums)

        ans_list=[]

        if k==1:
            return nums
        
        # 队列长度为k
        queue=nums[:k]

        # 排序队列 sorted_queue
        sorted_queue=sorted(queue)

        ans_list.append(sorted_queue[-1])

        for i in range(k,nums_len):

            # 出队
            del sorted_queue[self.BinaryMethod(sorted_queue,queue[0])]
            del queue[0]

            # 入队
            queue.append(nums[i])

            if nums[i]>=sorted_queue[-1]:
                sorted_queue.append(nums[i])
            else:
                sorted_queue.insert(self.BinaryMethod(sorted_queue,nums[i]),nums[i])

            ans_list.append(sorted_queue[-1])
                
        return ans_list

    # 传入lst和target
    def BinaryMethod(self,lst,target):

        # 左右指针
        left_pointer=0
        right_pointer=len(lst)-1
        
        while left_pointer<=right_pointer:

            mid_pointer=floor((left_pointer+right_pointer)/2)

            if lst[mid_pointer]>target:
                right_pointer=mid_pointer-1
            elif lst[mid_pointer]<target:
                left_pointer=mid_pointer+1
            else:
                return mid_pointer

        return left_pointer
        

官方题解:优先队列(堆)

class Solution:
    def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
        n = len(nums)

        # 注意 Python 默认的优先队列是小根堆
        q = [(-nums[i], i) for i in range(k)]
        heapq.heapify(q)

        ans = [-q[0][0]]

        for i in range(k, n):
            # 入队
            heapq.heappush(q, (-nums[i], i))

            # 判断是否需要出队:若堆顶元素在滑动窗口内则无需出队
            while q[0][1] <= i - k:
                heapq.heappop(q)

            ans.append(-q[0][0])
        
        return ans

优先队列也是一种队列,只不过不同的是,优先队列的出队顺序是按照优先级来的;在有些情况下,可能需要找到元素集合中的最小或者最大元素,可以利用优先队列来完成操作,优先队列ADT是一种数据结构,它支持插入和删除最小值操作(返回并删除最小元素)或删除最大值操作(返回并删除最大元素)。

堆(heap)是一种有特殊用途的数据结构,用来在一组变化频繁(发生增删查改的频率较高)的数据集中查找最值

堆在物理层面上,表现为一组连续的数组区间,将整个数组看作是堆。

堆在逻辑结构上,一般被视为是一颗完全二叉树

满足任意结点的值都大于其子树中结点的值,叫做大堆,或者大根堆,或者最大堆;反之,则是小堆,或者小根堆,或者最小堆。当一个堆为大堆时,它的每一棵子树都是大堆。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值