Java实现滑动窗口法

基本的滑动窗口法异常简单

逻辑基本为 在一个数组中 准备一个n大小的连续区域 比如{5,7,8,3,2,4,8,0,6}这个数组,我们用两个指针维持一个3大小的区域{5,7,8},每"走"一步 就把它的左指针 右指针向右移动一格,

这个移动的区域就叫做滑动窗口

 

 

本文中的滑动窗口法

用左右指针维护一个N大小的"窗口",这个窗口中存储的是元素的下标,加入数据时(移动右指针)要求窗口内严格由大到小(这里指的是下标对应的值),如果不满足该条件,如果新加入元素时不满足该条件就弹出之前的元素,直到这个窗口在加入新元素后满足由大到小,删除数据(移动左指针)时,由于左指针对应元素在之前的过程中可能弹出去了(如果没弹出去就在当前窗口的最左面),所以只判断最左面元素和窗口第一个元素是否相等即可.通过这个窗口 我们可以得到:在当前窗口范围中成为最大值的优先级

举个流程例子:

{3,7,2,5,6,1,9,8} 窗口为3

开始左指针右指针都是0所以先扩充长度到3

加入3  窗口为{3}

加入7  不满足由大到小 弹出3 变成{} 再加入7  {7}

加入2  满足由大到小  {7,2}

窗口大小为3了

加入5 不满足由大到小  弹出2 加入5 {7,5}  对应左下标已经没了 不用删除

加入6 不满足由大到小  弹出5 加入6{7,6}  对应左下标就是7 删除7->{6}

加入1 满足由大到小  {6,1} 对应左下标2已经没了 不用删除 删除 

加入9 不满足由大到小  弹出7 6 1 加入9 {9} 对应左下标5已经没了 不用删除

加入8 满足由大到小  {9,8} 对应左下标6已经没了 不用删除

代码实现:

  public static int [] SlidingWindow(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;
		// L...R
		//     i
		for (int R = 0; R < arr.length; R++) { // 当前让 i -> [i] 进窗口 , i 就是 r
			// R -> 值  可以放在比他大的数后,或者空
			while (!qmax.isEmpty() && arr[qmax.peekLast()] <= arr[R]) {
				qmax.pollLast();
			}
			qmax.addLast(R);
			// 数进来了
			// 如果窗口没有形成W的长度之前,不弹出数字的
			if (qmax.peekFirst() == R - w) {
				qmax.pollFirst();
			}
			// 以上窗口更新做完了
			if (R >= w - 1) {//每滑动一格都会把第一个值放到结果里面
				res[index++] = arr[qmax.peekFirst()];
			}
		}
		return res;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值