基本数据结构(二)
单调栈
int a[N], n;
stack<int> stk;
int main() {
int n; cin >> n;
for (int i = 0; i < n; i ++ ) cin >> a[i];
for (int i = 0; i < n; i ++ ) {
// 先入栈的不小于当前值的元素在之后一定不会被访问到,至少只会访问较小的当前元素
while (stk.size() && stk.top() >= a[i]) stk.pop();
if (stk.empty()) cout << -1 << ' ';
else cout << stk.top() << ' ';
stk.push(a[i]);
}
return 0;
}
单调队列
// 滑动窗口
for (int i = 0; i < n; i ++ ) {
if (q.size() && i - q.front() >= k) q.pop_front(); // 若超出窗口范围则出队
while (q.size() && a[q.back()] > a[i]) q.pop_back(); // 先入队的较大的元素之后一定不会被访问
q.push_back(i);
if (i >= k - 1) cout << a[q.front()] << ' ';
}
模式匹配KMP算法
// 模式串s,长度为m;模板串p,长度为n,下标均从1开始
char p[N], s[M];
int n, m, ne[N];
void kmp() {
// 构造ne数组
// ne[i] = j 表示 p[1:j] == p[i - j:i]
for (int i = 2, j = 0; i <= n; i ++ ) {
while (j && p[i] != p[j + 1]) j = ne[j];
if (p[i] == p[j + 1]) j ++ ;
ne[i] = j;
}
for (int i = 1, j = 0; i <= m; i ++ ) {
while (j && s[i] != p[j + 1]) j = ne[j];
if (s[i] == p[j + 1]) j ++ ;
if (j == n) {
// p到头了,匹配成功
}
}
}