剑指offer-面试题65-滑动窗口的最大值

来源:互联网 发布:qq堂 for mac 编辑:程序博客网 时间:2024/05/22 14:29
package case65_maxInWindow;import java.util.ArrayDeque;import java.util.ArrayList;/** * 题目:给定一个数组和滑动窗口的大小,请找出所有滑动窗口里的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口, * 他们的最大值分别为{4,4,6,6,6,5}。 *  * @author WangSai * */public class maxInWindow {public static void main(String[] args) {int[] arr = { 2, 3, 4, 2, 6, 2, 5, 1 };int k = 3;int[] temp = getMax(arr, k);System.out.println("所有滑动窗口最大值所组成的数组,数组里面的元素为:");for (int i : temp) {System.out.print(i + " ");}System.out.println();int[] arr2 = { 2 };int k2 = 1;int[] temp2 = getMax(arr2, k2);System.out.println("所有滑动窗口最大值所组成的数组,数组里面的元素为:");for (int i : temp2) {System.out.print(i + " ");}}/** *  * @param arr,给定的数组 * @param k,窗口大小 * @return 每个滑动窗口的最大值组成的数组 */private static int[] getMax(int[] arr, int k) {// 异常值检测if (arr == null || arr.length <= 0 || k <= 0 || arr.length < k)throw new IllegalArgumentException("非法输入参数...");// 辅助队列,保存当前窗口的最大值的角标和次大值的角标ArrayDeque<Integer> queue = new ArrayDeque<>();// 辅助空间,保存当前窗口的最大值ArrayList<Integer> list = new ArrayList<>();// 把arr第一个元素角标压入队列里,辅助队列里保存角标是为了判断最大值是否已经出滑动窗口。如i-queue.peek()>=kqueue.add(0);// 把第一个窗口填满,并且把最大值的角标存到队列里。for (int i = 1; i < k; i++) {// 若当前元素大于队列里的最大元素时,清空队列,并且把当前元素入队。if (arr[i] > arr[queue.peek()]) {if (!queue.isEmpty())queue.clear();// 把最大值角标入队列queue.add(i);}// 若当前元素小于等于队列尾部元素,则把当前元素放在队列尾。因为该元素可能是下一个滑动窗口的最大值,所以要把对应的角标加入到辅助队列里。else if (arr[i] <= arr[queue.peekLast()]) {queue.add(i);}// 若当前元素大于队尾元素,则队尾元素一直出栈,直到存在不小于它的数,然后把该元素角标加入队列。else {while (arr[i] > arr[queue.peek()]) {queue.pollLast();}queue.add(i);}}// 保存辅助队列第一个窗口的最大值list.add(arr[queue.peek()]);// 开始窗口滑动for (int i = k; i < arr.length; i++) {// 判断辅助队列中的最大值是否已经在窗口中滑动出去。if (i - queue.peek() >= k)queue.pollFirst();// 判断当前的值和队列头部的值大小,若当前值大于队列首部,即比辅助队列里的值都大if (arr[i] > arr[queue.peek()]) {queue.clear();queue.add(i);}// 若当前元素小于等于队列尾部元素,则把当前元素放在队列尾。else if (arr[i] <= arr[queue.peekLast()]) {queue.add(i);}// 若当前元素大于队尾元素,则队尾元素一直出栈,直到存在不小于它的数else {while (arr[i] > arr[queue.peekLast()]) {queue.pollLast();}queue.add(i);}// 保存辅助队列第一个窗口的最大值list.add(arr[queue.peek()]);}// 把角标值转换成数组元素。int[] temp = new int[list.size()];for (int i = list.size() - 1; i >= 0; i--) {temp[i] = list.get(i);}// 返回最大值组成的数组return temp;}}

0 0
原创粉丝点击