面试热题(滑动窗口最大值)

给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

返回 滑动窗口中的最大值 

输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解释:
滑动窗口的位置                最大值
---------------               -----
[1  3  -1] -3  5  3  6  7       3
 1 [3  -1  -3] 5  3  6  7       3
 1  3 [-1  -3  5] 3  6  7       5
 1  3  -1 [-3  5  3] 6  7       5
 1  3  -1  -3 [5  3  6] 7       6
 1  3  -1  -3  5 [3  6  7]      7

 如果你刚看见这道题你会怎么想?三秒告诉我?3...2...1...,时间到!!!

       首先是滑动窗口,一听到这个名字,我们就应该立刻的想到双指针,双指针这个大方向是错不了,我们再看,要每次取到范围内的最大值,除了最大堆就是优先队列可以做到这件事,接下来我们先用最大堆进行解题

        最大堆就是其实就是一棵树,通过上浮和下浮使得堆顶是最大值或者最小值,Java中默认是最小堆,所以我们如果是想每次取到范围内的最大值,

  PriorityQueue queue=new PriorityQueue<>(new Comparator() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2-o1;//最大值   默认是o1-o2
            }
        });
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

需要对堆的比较器进行重写,构造一个最大堆

面试热题(滑动窗口最大值)_第1张图片

面试热题(滑动窗口最大值)_第2张图片

 面试热题(滑动窗口最大值)_第3张图片

 维护一个一个列表进行最大值的维护

List list=new ArrayList<>();
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
        for(int right=0;right< nums.length;right++){
            if(right

结果,不出意外:

       怎么办?时间超时了怎么办?堆的上浮和下沉确实浪费了大量的时间,所以我们使用另外一种数据结构解决本题(优先队列)

面试热题(滑动窗口最大值)_第4张图片

    //维护一个单调队列
    class MaxQueue{
        private LinkedList queue=new LinkedList<>();
        //添加
        public void push(int x){  
         //队列不为空,队尾元素如果小于当家加入元素,直接扔出去
            while(!queue.isEmpty()&&queue.getLast()

 核心代码:

  int left=0;
         for(int right=0;right< nums.length;right++){
             if(right

结果,不出意外:

 上源代码:

  public int[] maxSlidingWindow(int[] nums, int k) {
         if(nums==null){
             return null;
         }
         MaxQueue window=new MaxQueue();
         List list=new ArrayList<>();
         int left=0;
         for(int right=0;right< nums.length;right++){
             if(right queue=new LinkedList<>();
        //添加
        public void push(int x){
            while(!queue.isEmpty()&&queue.getLast()

你可能感兴趣的:(热题Hot100,面试,算法,数据结构)