维护左右边第一个小的值(滑动窗口)

前言:这个题目和我之前写的一个题目差不多,我们可以维护左右边第一个小的,然后我们就可以快速枚举


题目地址
在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;
#define ll long long

const int N = (int)1e6 + 10;
int a[N], h[N];
int qian[N];
int n;
int lef[N], rig[N]; // 记录左边和右边第一个小于这个数的坐标

void fun() {
	deque<int> q;
	for (int i = 1; i <= n; i++) {
		int u = h[i];
		while (q.size() && h[q.back()] > u) {
			int v = q.back();
			q.pop_back();
			rig[v] = i;
		}
		q.push_back(i);
	}
	while (q.size()) {
		int u = q.back(); q.pop_back();
		rig[u] = n + 1;
	}
}

void fun1() {
	deque<int> q;
	for (int i = n; i; i--) {
		int u = h[i];
		while (q.size() && h[q.back()] > u) {
			int v = q.back();
			q.back();
			lef[v] = i;
		}
		q.push_back(i);
	}
	while (q.size()) {
		int u = q.back(); q.pop_back();
		lef[u] = 0;
	}
}

signed main() {
	cin >> n;
	for (int i = 1; i <= n; i++) {
		scanf("%d", &a[i]);
		qian[i] = qian[i - 1] + a[i];
	}
	for (int i = 1; i <= n; i++) {
		scanf("%d", &h[i]);
	}
	fun(); fun1();
	int ans = 0;
	for (int i = 1; i <= n; i++) {
		int hi = h[i];
		int len = qian[rig[i] - 1] - qian[lef[i]];
		ans = max(ans, hi * len);
	}
	cout << ans;
	return 0;
}

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 滑动窗口的最大指的是一个固定长度的数字序列中的最大。它通常用于数据流处理,并且可以使用一个队列来维护滑动窗口内的数字。 以下是一个用 Python 实现滑动窗口的最大的示例代码: ``` from collections import deque def max_in_sliding_window(nums, k): if not nums: return [] q = deque() res = [] for i in range(len(nums)): while q and nums[q[-1]] <= nums[i]: q.pop() q.append(i) if q[0] == i - k: q.popleft() if i >= k - 1: res.append(nums[q[0]]) return res ``` 其中 `nums` 是输入数字序列,`k` 是滑动窗口的长度。该代码返回每个滑动窗口的最大组成的列表。 ### 回答2: 滑动窗口的最大是一种常用的算法思想,可以用于解决一些与连续子数组相关的问题。在Python中,我们可以使用双端队列实现滑动窗口的最大查找。 具体实现过程如下: 1. 首先,我们需要创建一个双端队列(deque)来存储滑动窗口中的元素索引。我们将队列中的索引按照元素大小降序排列,以便可以快速找到最大。 2. 然后,我们需要遍历整个数组,并在每次迭代中执行以下步骤: a. 检查双端队列的头部元素(即索引)是否已经超出当前窗口的范围。如果超出了范围,我们需要将其从队列中弹出。 b. 将当前元素添加到队列中。在添加之前,我们需要将队列中所有小于当前元素的索引都弹出,以保持队列中的索引按照元素大小降序排列。 c. 检查当前索引与窗口的起始位置的差是否大于等于窗口的大小K。如果是,说明当前窗口已经满了,我们可以将队列的头部元素作为当前窗口的最大。 3. 最后,我们可以将所有窗口的最大存储在一个数组中,并返回该数组作为最终结果。 以下是一个示例代码: ``` from collections import deque def maxSlidingWindow(nums, k): result = [] queue = deque() for i in range(len(nums)): # 检查队列的头部元素是否超出窗口范围 if queue and queue[0] <= i - k: queue.popleft() # 弹出所有小于当前元素的索引 while queue and nums[queue[-1]] < nums[i]: queue.pop() # 将当前元素添加到队列中 queue.append(i) # 检查窗口是否已经满了 if i >= k - 1: result.append(nums[queue[0]]) return result # 测试 nums = [1,3,-1,-3,5,3,6,7] k = 3 print(maxSlidingWindow(nums, k)) ``` 以上代码的输出为:[3, 3, 5, 5, 6, 7]。 这样,我们就成功实现了滑动窗口的最大查找的功能。 ### 回答3: 滑动窗口的最大是指在一个给定数组中,长度为k的窗口从左至右滑动,每次滑动窗口都需要找到窗口中的最大。下面是一个用Python实现滑动窗口最大的示例代码: ``` def find_max_in_window(arr, k): if not arr or k <= 0 or k > len(arr): return [] max_nums = [] deque = [] for i in range(len(arr)): # 检查队首元素是否还在窗口范围,如果不在则删除 if deque and deque[0] <= i - k: deque.pop(0) # 如果当前遍历元素大于队尾元素,删除队尾元素直到当前元素小于队尾元素或队列为空 while deque and arr[i] >= arr[deque[-1]]: deque.pop() deque.append(i) # 当前窗口已形成 if i >= k - 1: max_nums.append(arr[deque[0]]) return max_nums ``` 在这个代码中,我们使用一个双端队列(deque)来保存当前窗口中的元素索引。其中deque的特点是队首元素是当前窗口中的最大,队列中较小的元素按照递减顺序排列。在遍历数组时,我们首先检查队首元素是否还在窗口范围内,如果不在窗口范围内,删除队首元素。然后,我们将当前元素与队列中的元素进行比较,如果当前元素比队尾元素大,删除队尾元素,直到当前元素小于队尾元素或队列为空。最后,将当前元素的索引加入队列中。 当遍历到第k个元素时,当前窗口已经形成,此时队首元素就是当前窗口中的最大,将其添加到结果集中。接着,继续遍历数组,每次遍历窗口滑动一次,重复上述步骤找到最大,直到遍历完整个数组。 调用该函数,可以输出滑动窗口的最大。如下所示: ``` arr = [1, 3, -1, -3, 5, 3, 6, 7] k = 3 max_nums = find_max_in_window(arr, k) print(max_nums) ``` 输出结果为:[3, 3, 5, 5, 6, 7],表示滑动窗口的最大为3, 3, 5, 5, 6, 7。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wniuniu_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值