栈和队列(7)-- 生成窗口最大值数组

要求:

有一个整数型数组arr和一个大小为w的窗口,窗口从最左边滑到最右边,每次挪动一位,求在窗口为w大小里面最大值排列。

例如,数组为[4,3,5,4,3,3,6,7], 窗口大小为3时:

[4      3      5]     4      3      3      6      7         窗口最大值为5

 4     [3      5      4]     3      3      6      7         窗口最大值为5

 4      3     [5      4      3]     3      6      7         窗口最大值为5

 4      3      5     [4      3      3]     6      7         窗口最大值为4

 4      3      5      4    [3      3      6]      7          窗口最大值为6

 4      3      5      4      3    [3      6       7]         窗口最大值为7

实现一个函数,输入为整数型arr数组,窗口大小为w,输出为一个长度为arr.length - w + 1的数组res,res[i]表示每一次窗口的最大值。

思考:

普通的比较法,时间复杂度O(N*w)的解法太费时,用另外一种解法。

假设遍历到arr[i],qmax队列为存放到数组arr的下标:

1.如果qmax为空,则将下标i放到qmax中;

2.如果qmax不为空,取出qmax队尾的值记为j;

3.如果arr[i] => arr[j],则弹出qmax[j];

4.如果arr[i] < arr[j],则将i加入到qmax里面去,若i=>w-1,则res写入arr[qmax的队头];若小于则不写入。

 弹出规则为:

当qmax队头下标等于i - w 说明当前qmax对头的下标已经过期了,弹出当前队头。
实验代码:
<pre name="code" class="java">package algorithm_7;

import java.util.Arrays;
import java.util.LinkedList;

public class algorithm_7 {

	public static int[] getMaxWindow(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){
				qmax.pollFirst();
			}
			if(i >= w - 1){
				res[index++] = arr[qmax.peekFirst()];
				
			}
		}
	return res;
	}
	
	
	
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] arr_test = {4,3,5,4,3,3,6,7};
		int w_test = 3;
		System.out.println("result = "+Arrays.toString(getMaxWindow(arr_test,w_test)));
		
	}

}

实验结果:

 
result = [5, 5, 5, 4, 6, 7]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值