剑指offer——滑动窗口的最大值(好题,数据结构)
来源:互联网 发布:预科生的贩毒网络豆瓣 编辑:程序博客网 时间:2024/05/18 20:11
题目描述
给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{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]}。
思路:
假设n为数组长度,m为窗口的长度
蛮力法(O(nm))
可以用PriorityQueue实现一个最大堆(O(nmlogm)),或者直接冒泡法(O(n*m*m))
重温下PriorityQueue的使用(很傻的方法了)
import java.util.*;public class Solution { public ArrayList<Integer> maxInWindows(int [] num, int size) { ArrayList<Integer> list = new ArrayList(); if(num==null||size>num.length||size==0) return list; PriorityQueue<Integer> maxHeap = new PriorityQueue(num.length, new Comparator<Integer>(){ public int compare(Integer o1, Integer o2) { return o2-o1; } }); for(int i = 0; i<=num.length-size; i++){ maxHeap.clear(); for(int j = i; j<i+size; j++){ maxHeap.offer(num[j]); } list.add(maxHeap.peek()); } return list; }}
其实也可以用一个队列来保存最大值,参考栈的min函数那道题。
剑指offer思路:双端队列
/**
用一个双端队列,队列第一个位置始终保存当前窗口的最大值,当窗口滑动一次
1.判断当前最大值是否过期
2.新增加的值从队尾开始比较,把所有比他小的值丢掉
*/
import java.util.*;public class Solution { public ArrayList<Integer> maxInWindows(int [] num, int size) { ArrayList<Integer> res = new ArrayList<>(); if(num==null||size>num.length||size == 0) return res; int begin; ArrayDeque<Integer> q = new ArrayDeque<>(); // 声明一个双端队列,队列中存储的是下标值! for(int i = 0; i < num.length; i++){ begin = i - size + 1; // 滑动窗口起始元素的下标值 if(q.isEmpty()) q.add(i); // 将数据插在队尾 // 如果begin比队列的头值大,说明这个头值已失效(在窗口外); //只要q不为空,则每次都会进行头值有效性判断 else if(begin > q.peekFirst()) q.pollFirst(); while((!q.isEmpty()) && num[q.peekLast()] <= num[i]) //与即将加入的元素进行比较,把队尾中不可能成为最大值候选的元素全部删除 q.pollLast(); q.add(i); if(begin >= 0) res.add(num[q.peekFirst()]); } return res; }}
直接的思路
/* * 找出每个窗口里的最大值,每次只要判断最大值是否超出范围,以及新加入的值是否比该值更大 */ public ArrayList<Integer> maxInWindows(int[] num, int size) { ArrayList<Integer> result = new ArrayList<Integer>(); if (num == null || size <= 0 || num.length < size) return result; int max = findMaxIndex(num, size, 0); result.add(num[max]); for (int i = size; i < num.length; i++) { if (num[max] < num[i]) max = i; // 如果max不在滑动窗口范围内,重新找最大值 if (max <= i - size) { max = findMaxIndex(num, size, i - size + 1); } result.add(num[max]); } return result; } /* * 查找num指定范围内的最大值的下标 */ private int findMaxIndex(int[] num, int size, int begin) { int max = begin; int end = (begin + size) > num.length ? num.length : (begin + size); for (int i = begin; i < end; i++) { if (num[max] < num[i]) { System.out.println("num[max]:" + num[max] + " " + "num[i]:" + num[i]); max = i; System.out.println("max=" + max); } } return max; }
阅读全文
0 0
- 剑指offer——滑动窗口的最大值(好题,数据结构)
- 剑指offer—滑动窗口的最大值
- 剑指offer—滑动窗口的最大值
- 剑指offer — 滑动窗口的最大值
- 剑指offer(C++)——滑动窗口的最大值
- 剑指offer——滑动窗口的最大值
- 剑指Offer—64—滑动窗口的最大值
- 剑指offer——63.滑动窗口的最大值
- 剑指offer 65 - 滑动窗口的最大值
- 《剑指offer》滑动窗口的最大值
- 剑指offer:滑动窗口的最大值
- 剑指offer:滑动窗口的最大值
- [剑指offer]滑动窗口的最大值
- 《剑指offer》:[65]滑动窗口的最大值
- 剑指Offer--065-滑动窗口的最大值
- 剑指offer-滑动窗口的最大值
- 【剑指offer】滑动窗口的最大值
- 《剑指Offer》 滑动窗口的最大值
- 内存映射的解释
- 洛谷 P1070 道路游戏(动态规划)
- 根据屏幕宽高比适配文字大小 和 布局
- Linux DTS(Device Tree Source)设备树详解之二(dts匹配及发挥作用的流程篇)
- Mysql索引与优化
- 剑指offer——滑动窗口的最大值(好题,数据结构)
- JavaScript内置对象
- Hadoop,HA高可用集群
- flashsim源码阅读7-7笔记
- vim ctrl+s 就死
- JAVA状态模式2
- mysql中timestamp数据类型
- java synchronized类锁,对象锁详解(转载)
- Maven使用tomcat7运行报错:Unable to determine URL for WEB-INF/classes