剑指offer系列之六十三:滑动窗口的最大值
2015-12-21 14:23
387 查看
题目描述
给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。
这实际上可以看成是TCP/IP中差错控制中滑动窗口的算法实现了。由于每次窗口大小是固定的,所以可以创建一个指针用于指向当前窗口的第一个值,而且位置该值是当前窗口的最大值的下标。这么做的好处在于每次窗口移动只需要从第一个位置取值就可以,时间复杂度是O(1)。那么具体需要在获取每个窗口的值得时候与队列中(需要创建一个队列用于保存每个窗口最大值的下标)的队尾指针的元素进行比较,如果比当前遍历到的元素小的话,需要把队尾元素移除,因为我们需要获得的是最大值。这样一直遍历到最后一个元素,就把每个窗口的最大值获取到了。下面是具体的实现代码(已被牛客AC):
给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。
这实际上可以看成是TCP/IP中差错控制中滑动窗口的算法实现了。由于每次窗口大小是固定的,所以可以创建一个指针用于指向当前窗口的第一个值,而且位置该值是当前窗口的最大值的下标。这么做的好处在于每次窗口移动只需要从第一个位置取值就可以,时间复杂度是O(1)。那么具体需要在获取每个窗口的值得时候与队列中(需要创建一个队列用于保存每个窗口最大值的下标)的队尾指针的元素进行比较,如果比当前遍历到的元素小的话,需要把队尾元素移除,因为我们需要获得的是最大值。这样一直遍历到最后一个元素,就把每个窗口的最大值获取到了。下面是具体的实现代码(已被牛客AC):
package com.rhwayfun.offer; import java.util.ArrayDeque; import java.util.ArrayList; public class MaxNumInWindow { public ArrayList<Integer> maxInWindows(int[] num, int size) { ArrayList<Integer> maxList = new ArrayList<Integer>(); if(size <= 0) return maxList; //创建一个双端队列保存每个滑动窗口的最大值得下标 ArrayDeque<Integer> queue = new ArrayDeque<Integer>(); //创建一个变量start用于记录当前滑动窗口的最大值的下标 int start = 0; for (int i = 0; i < num.length; i++) { start = i + 1 - size;//当start大于的时候表示第一个窗口已经不能再移动了 if(queue.isEmpty()){ queue.add(i); }else if(start > queue.peekFirst()){//这个条件表示当前窗口start的值比上一个窗口的start更大 queue.pollFirst(); } while(!queue.isEmpty() && num[queue.peekLast()] <= num[i]){ //这种情况表示,队列队尾位置对应的元素比当前元素更小,就移除他,因为需要得到的是窗口最大值 queue.pollLast(); } queue.add(i); if(start >= 0){ //实际上当start=0的时候第第一个滑动窗口,这时队列中保存的是第一个滑动窗口最大值的下标,直接添加就行 maxList.add(num[queue.peekFirst()]); } } return maxList; } public static void main(String[] args) { int[] num = {2,3,4,2,6,2,5,1}; ArrayList<Integer> list = new MaxNumInWindow().maxInWindows(num, 3); System.out.println(list); } }
相关文章推荐
- JavaScript设计模式学习笔记
- 编写高质量JavaScript的有效方法
- Jquery easyui中的有效性检查
- JavaScript模式笔记
- JavaScript对象中的属性(可写,可配置,可枚举,value,getter,setter)
- html tabel colspan和rowspan
- js设置组合快捷键/tabindex功能的方法
- 高性能JavaScript学习笔记
- js复选框相关事件
- 剑指offer系列之六十二:数据流中的中位数
- js数据存放
- JQuery获取Checkbox组的值
- 先执行javascript在执行ios原生函数
- js变量提升
- 【JavaScript】JavaScript获取当前时间
- 解决setTimeout 计时器重复调用的问题
- Javascript中null值,特别注意的两点
- css3 常用命令总结(不定期更新)
- JAVASCRIPT中NULL值,特别注意的两点
- jquery获取地址栏的get参数