面试题59(剑指offer)--队列的最大值

题目一: 滑动窗口的最大值。给定一个数组和滑动窗口的大小,请找出所有滑动窗口里的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}。 数组{2,3,4,2,6,2,5,1}的滑动窗口如下:

数组中的滑动窗口滑动窗口中的最大值
[2,3,4],2,6,2,5,14
2,[3,4,2],6,2,5,14
2,3,[4,2,6],2,5,16
2,3,4,[2,6,2],5,16
2,3,4,2,[6,2,5],16
2,3,4,2,6,[2,5,1]5

解法:

	/**
     * 利用大小为size的大顶堆,则堆顶即为滑动窗口最大值
     * @param num
     * @param size
     * @return
     */
	public ArrayList<Integer> maxInWindows(int [] num, int size) {
        ArrayList<Integer> res=new ArrayList<>();
        if (size<1||size>num.length){
            return res;
        }
        PriorityQueue<Integer> heap=new PriorityQueue<>(((o1, o2) -> o2-o1));
        for (int i = 0; i <size ; i++) {
            heap.add(num[i]);
        }
        res.add(heap.peek());
        int len=num.length;
        for (int i=0,j=size;j<len;i++,j++){
            heap.remove(num[i]);
            heap.add(num[j]);
            res.add(heap.peek());
        }
        return res;
    }

题目二: 队列的最大值。请定义一个队列并实现函数max得到队列里的最大值,要求函数max、push_back和
pop_front的时间复杂度都是O(1)。

import java.util.*;
/**
 * 利用双端队列存储最大值以及可能最大值,当双端队
 * 列有一个元素进队列,如果该元素大于双端队列队尾,
 * 则移除队尾,直至该元素小于队尾,然后入队,若小
 * 于队尾直接入队。queue存储元素,maxVal存储当前
 * 最大值,以及可能的最大值
 */
public class MaxValueInQueue {
    private LinkedList<Integer> queue=new LinkedList<>();
    private ArrayDeque<Integer> maxVal=new ArrayDeque<>();
    private void push_back(Integer val){
        queue.add(val);
        if (maxVal.isEmpty()){
            maxVal.push(val);
        }else if (val>maxVal.peekLast()){
            while (!maxVal.isEmpty()&&val>maxVal.peekLast()){
                maxVal.pollLast();
            }
            maxVal.add(val);
        }else {
            maxVal.add(val);
        }
    }
    private void pop_front(){
        if (queue.peek().equals(maxVal.peekFirst())){
            maxVal.pollFirst();
        }
        queue.pop();
    }
    private int max(){
        if (maxVal.size()>0){
            return maxVal.peek();
        }
        return -1;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值