数据结构·单调栈和单调队列

思想

  • 本质都是讲原本 O ( n 2 ) O(n^2) O(n2)的算法优化为 O ( n ) O(n) O(n),都是利用使用一个容器维护某段区间,节省一段for循环,同时这段区间维持单调性
  • 出发点:删除容器内的冗余元素。

单调栈

例题:830. 单调栈

应用:左边第1个小于当前数的数

  • 暴力做法是两个for循环,第一层循环表示当前数,第二层循环用于搜索第一个小于当前数的数。
  • 使用容器存储第二个for循环中遍历的数,意味着我们可以去掉一重for循环。
    • 方便查询目标数
    • 因此我们想到可以优化容器内的数据存储,删除冗余的数据
  • 删除容器中的冗余元素 :我们发现如果i<j,且ai>aj,那么ai一定是当前容器中的冗余元素,我们就可以删去它。此时容器末位的元素就是我们需要的第1个小于当前数的数。(如果容器为空,则返回-1)
  • 然后按照这个规则,容器内的元素就变成单调递增了,然后我们用栈方便我们的实现。
cpp 复制代码
int n, a;
stack<int>st;
void solve() {
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a;
		while (!st.empty() && st.top() >= a) {
			st.pop();
		}
		if (st.empty())cout << -1 << " ";
		else {
			cout << st.top() << " ";
		}
		st.push(a);
	}
}

单调队列

例题:154. 滑动窗口

应用:滑动窗口最大值或者最小值

  • 暴力方法遍历每一个窗口和窗口内元素
  • 尝试使用一个容器维护当前窗口:
    • 这个容器需要实现窗口移动时容器大小减少以保持一致
    • 方便查询最大值或者最小值。
    • 因此我们想到可以优化容器内的数据存储,删除冗余的数据
  • 删除冗余数据:对于最小值的情况,j>i,aj<ai,那么之后窗口ai一定不会被选中,因此直接删除aj,由此我们得到一个单调递增的数组。此时,头部元素就是最小值
  • 最后使用队列方便我们的实现。
cpp 复制代码
int n,k,a[1000009];
deque<int>q;
void solve() {
	cin >> n >> k;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	// min
	for (int i = 1; i <= n; i++) {
		if (i >= k + 1) {
			if (q.size()&&q.front() == a[i - k]) {
				q.pop_front();
			}
		}
		while (q.size() && q.back() > a[i]) {
			q.pop_back();
		}
		q.push_back(a[i]);
		if (i >= k) {
			cout << q.front() << " ";
		}
	}
	cout << endl;
	q.clear();
	// max
	for (int i = 1; i <= n; i++) {
		if (i >= k + 1) {
			if (q.size() && q.front() == a[i - k]) {
				q.pop_front();
			}
		}
		while (q.size() && q.back() < a[i]) {
			q.pop_back();
		}
		q.push_back(a[i]);
		if (i >= k) {
			cout << q.front() << " ";
		}
	}
	cout << endl;
}
相关推荐
xiangyun6110 小时前
【408数据结构 08】队列:循环队列判空判满,408年年考,一次讲清
c语言·开发语言·数据结构·c++·算法
xiangyun6110 小时前
【408数据结构 06】双链表、循环链表、静态链表
c语言·开发语言·数据结构·c++·算法
OKkankan11 小时前
LangChain 能力详解!:输出解析、RAG、向量数据库与 Retriever 检索器
数据结构·python·langchain·ai应用
蓝速科技11 小时前
便民服务大厅 AI 数字人一体机场景适配与落地指南丨蓝速科技
大数据·网络·数据结构·人工智能·自然语言处理·数据分析·运维开发
xxwxx__12 小时前
C++ AVL 树深度剖析:平衡二叉搜索树原理、源码与面试考点
数据结构·c++
Logic10112 小时前
C语言/数据结构数组题解:数字列表加一(Plus One)——进位处理与数组扩展
c语言·数据结构·模拟·数组·时间复杂度·算法题·进位
xxwxx__15 小时前
C++ STL set 与 map 全套详解:关联式容器、红黑树底层、代码坑点、刷题实战
数据结构·c++
程曦曦16 小时前
MySQL 生产库误删 98 张表后的时间点恢复实战:从 binlog 解析到资金对账
linux·数据结构·其他·算法·ubuntu·运维开发
郝学胜-神的一滴16 小时前
Effective Python 条款 13:善用星号解包,告别下标切片拆分的坑
服务器·开发语言·数据结构·python·程序人生·pycharm
Logic10116 小时前
C语言/数据结构位运算题解:异或XOR找出流水线上的“独特零件编号“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质