Java滑动窗口实现当前窗口内最大值输出

    昨天在做一道题目看到这样一道题目:对一个给定的数组来说,要求给定一个指定长度的滑动窗口,然后滑动窗口每次右移一位,要输出当前窗口最大值的集合,这个问题说实在并不是很困难,看到之后也的确是很快就做了出来,而且用了不同的方法,在上网搜的时候无意间看到了一位大牛写的关于这个问题的解法,不得不说自己考虑的还是很不够 的,不说代码的整洁度,单单从实现的方式以及实现的时间复杂度来说我就不行了。

    假定给定数组长度为n,窗口大小为w我的时间复杂度算下来怎么样是O(n*w)级别的,但是他的却是O(n),级别的,在这里参考他的想法给出下面的程序,作为自己的学习记录:


import java.util.LinkedList;
import java.util.Random;

public class GetMaxValue{

	public static int[] getCurrentWindowMaxValue(int[] arr, int w) {
		if (arr == null || w < 1 || arr.length < w) {
			return null;
		}
		LinkedList<Integer> qmax = new LinkedList<Integer>();
		int[] res = new int[arr.length - w + 1];
		int index = 0;
		for (int i = 0; i < arr.length; i++) {
			while (!qmax.isEmpty() && arr[qmax.peekLast()] <= arr[i]) {
				qmax.pollLast();
			}
			qmax.addLast(i);
			if (qmax.peekFirst() == i - w) {//arr[3,4,5],而此时qmax下标为2,当前下标已经过期,则弹出
				qmax.pollFirst();
			}
			if (i >= w - 1) {//如i=3,w=3,此时窗口下标应为[1,2,3],index为0,故此时index加1,即窗口右移
				res[index++] = arr[qmax.peekFirst()];//当前窗口的最大值,即窗口右移一位后的首部
			}
		}
		return res;
	}

	// for test
	public static void printArray(int[] arr) {
		for (int i = 0; i != arr.length; i++) {
			System.out.print(arr[i] + " ");
		}
		System.out.println();
	}
    
	public static void printEach(int[] arr){
		System.out.println("当前数组为:");
		for(int j=0;j<arr.length;j++){
			System.out.print(arr[j] + ",");
		}
		System.out.println();
	}
	public static void main(String[] args) {
		int[] arr_test = new int[10];
		Random ran = new Random();
		for (int i=0;i<10;i++){
			int random = ran.nextInt(100);
			arr_test[i]=random;
		}
		printEach(arr_test);
		int w = 3;
		printArray(getCurrentWindowMaxValue(arr_test, w));

	}

}

结果如下:

当前数组为:
39,14,63,52,43,49,72,15,89,43,
63 63 63 52 72 72 89 89 
当前数组为:
60,74,79,40,36,41,5,26,32,78,
79 79 79 41 41 41 32 78 
当前数组为:
44,56,41,66,43,43,21,65,23,42,
56 66 66 66 43 65 65 65 


阅读更多

扫码向博主提问

Together_CZ

非学,无以致疑;非问,无以广识
  • 擅长领域:
  • 深度学习
  • 机器学习
  • 数据挖掘
  • 异常检测
  • 恶意网站检测
去开通我的Chat快问
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页