8.队列中的最大值

1.题目描述:给定一个数组和滑动窗口的最大值,找出所有滑动窗口中的最大值。例如 nums = [2,5,3,6,4,8,5,6,9,7],window = 4 则结果为 res = [6, 6, 8, 8, 8, 9, 9].

2.解题思路:我们创建一个队列用于存储值的索引。如果新进入队列的值比队列中已有下标对应的数字大的话,这些小的值不可能成为最大值,我们把它们从队列中移除,如果新进入队列的值比队列中已有下标对应的数字小的话,可能成为下个窗口的最大值,所以保留。

步骤插入数字滑动窗口   队列中的下标(数值)最大值
0220(2)N/A
152, 51(5)N/A
232,  5,3 1(5), 2(3)N/A
362, 5, 3, 63(6)6
445, 3, 6, 43(6), 4(4)6
583, 6, 4, 8
5(8)8
656, 4, 8, 5
5(8), 6(5)8
764, 8, 5, 6
5(8), 7(6)8
898, 5, 6, 9
8(9)9
975, 6, 9, 7
8(9), 9(7)9
3.Java代码:
public class Main {
	
	public static int[] MaxValueOfQueue(int[] nums, int window) {
		
		if(nums.length == 0 || window <= 0) {
			System.out.println("nums is null!!");
			return new int[]{0};
		}
		//首先把第一个窗口的最大值找出来
		int max = nums[0];
		int index = 0;
		for (int i = 0; i < Math.min(nums.length, window); i++) {
			if(max < nums[i]){
				max = nums[i];
				index = i;
			}
		} 
		//如果窗口长大于数组长度,问题就等同于找数组中的最大值。
		if(window >= nums.length)return new int[]{max};
		
		int[] res = new int[(nums.length-window)+1];
		//首先将第一个窗口的最大值存入res。
		res[0] = max;
		Queue<Integer> queue = new LinkedList<>();
		//把第一个窗口的最大值索引入队列
		queue.offer(index);
		//从第二个窗口逐渐滑动窗口
		for (int i = window; i < nums.length; i++) {
			/*---------以下代码是将比入队列小的值移除--------*/
			int len = queue.size();
			while(len>0){
				//如果大于一个数,把这个数之后的所有数字移除
				if(nums[i] > nums[queue.peek()]){
					while(len > 0){
						queue.poll();
						len--;
					}
				}
				//否则把队头元素移到队尾
				else {
					queue.offer(queue.poll());
					len--;
				}
			}
			queue.offer(i);
			//如果下次队头的值出窗的话,将这个元素移除。
			if(i - queue.peek() >= window - 1)res[i - window + 1] = nums[queue.poll()];
			//否则直接取队头元素而不移除
			else res[i - window + 1] = nums[queue.peek()];
		}
		return res;
	}
	public static void main(String[] args) {
		int[] nums = new int[]{};
		for(int i : MaxValueOfQueue(nums, 4)){
			System.out.println(i);
		}
		
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值