题意
给定一个长度为的数组。找它的长度为
的区间中的最大值,求这些所有的最大值的集合里的最小值。
思路
- 利用单调栈,对于每一个
,找出来左边第一个比它大的,找出来右边第一个比它大的。并且把它们的下标分别存
和
里。
- 对于每一个
,它能作为最小值的最长区间已经确定了。那么就可以通过比较得到一部分长度的区间的最优答案了。
如样例1,执行到这里的时候就是[1,3,1061109567,1061109567,5,6]
- 此时区间长度为3和4的时候,最小的可选最大值仍未确定。那么就应该从高位继承。
为什么是从高位继承呢?因为要选定的是集合的最大值,而高位的值必然是低位的值的可选项,而低位的则未必是高位的可选项。
Solution
class Solution {
public:
static const int N = 1e5 + 5;
int L[N], R[N], s[N], t;
vector<int> getMinimums(vector<int>& a) {
int n = a.size();
s[t = 0] = -1;
for (int i = 0; i < n; ++i) {
while (t && a[s[t]] <= a[i]) --t;
L[i] = s[t]; //左边第一个比a[i]大的下标
s[++t] = i;
}
s[t = 0] = n;
for (int i = n - 1; ~i; --i) {
while (t && a[s[t]] <= a[i]) --t;
R[i] = s[t]; //右边第一个比a[i]大的下标
s[++t] = i;
}
/*
-1 -1 -1 2 2 -1
1 2 5 4 5 6
*/
vector<int> ans(n, 0x3f3f3f3f);
for (int i = 0; i < n; ++i) // a[i]作为最大值的最长区间
ans[R[i] - L[i] - 2] = min(ans[R[i] - L[i] - 2], a[i]);
for (int i = n - 2; ~i; --i) // 自高位继承
ans[i] = min(ans[i], ans[i + 1]);
return ans;
}
}; 
京公网安备 11010502036488号