求各个元素左边和右边的最近的小于(等于)的下标


最近的小于的计算过程:
实现的过程需要用到一个stack<==>st
黑盒:在st的元素都可以正确计算出最近小于的元素下标那么我们依次将arr中的元素入栈计即可
1.栈里面存储的是vector,vector存储的是元素的下标,同一个vector存储的这些下标对应的元素值是相同的
⒉栈从栈底到栈顶,vector对应的元素值是严格递增的,因为相同的值下标放到同一个vector里面了
3.当i下标想要入栈,必须保证i下标对应元素值大于等于栈顶vector对应的元素值或者栈空4.如果i下标对应元素值大于等于栈顶vector对应的元素值,直接入栈st.push({i))
5.如果i下标对应元素值小于栈顶vector对应的元素值,此时我们可以直到栈顶vector所有元素的左边最近小于元素下标和右边最近小于元素下标
6.左边最近小于元素下标是在栈顶下面压着的vector的最后一个元素7.右边最近小于元素下标是i
8.依次st.pop维护pop出来的vector里面所有元素最近最小下标,直到i下标对应元素值大于等于栈顶vector对应元素值,或者栈空

#include<bits/stdc++.h>
using namespace std;
class Solution {
public:
vector<pair<int, int>> getNearLessEqual(vector<int>& arr) {
vector<pair<int, int>> ret(arr.size());
stack<int> st;
for (int i = 0; i < arr.size(); i++) {
while (!(st.empty() || arr[i] > arr[st.top()])) {
int top = st.top(); st.pop();
int leftlessindex = st.empty() ? -1 : st.top();
ret[top].first = leftlessindex;
ret[top].second = i;
}
st.push(i);
}
while (!st.empty()) {
int top = st.top(); st.pop();
int leftlessindex = st.empty() ? -1 : st.top();
ret[top].first = leftlessindex;
ret[top].second = -1;
}
return ret;
}
vector<pair<int, int>> getNearLess(vector<int>& arr) {
vector<pair<int, int>> ret(arr.size());
stack<vector<int>> st;
for (int i = 0; i < arr.size(); i++) {
while (!(st.empty() || arr[i] >= arr[st.top()[0]])) {
vector<int> top = st.top(); st.pop();
int leftlessindex = st.empty() ? -1 : st.top().back();
for (auto x : top) {
ret[x].first = leftlessindex;
ret[x].second = i;
}
}
if (!st.empty() && arr[i] == arr[st.top()[0]]) {
st.top().push_back(i);
} else {
st.push({ i });
}
}
while (!st.empty()) {
vector<int> top = st.top(); st.pop();
int leftlessindex = st.empty() ? -1 : st.top().back();
for (auto x : top) {
ret[x].first = leftlessindex;
ret[x].second = -1;
}
}
return ret;
}
vector<pair<int, int>> getNearLessEqual_1(vector<int>& arr) {
vector<pair<int, int>> ret(arr.size());
stack<vector<int>> st;
for (int i = 0; i < arr.size(); i++) {
while (!(st.empty() || arr[i] > arr[st.top()[0]])) {
vector<int> top = st.top(); st.pop();
int leftlessindex = st.empty() ? -1 : st.top().back();
for (auto x : top) {
ret[x].first = leftlessindex;
ret[x].second = i;
}
}
if (!st.empty() && arr[i] == arr[st.top()[0]]) {
st.top().push_back(i);
} else {
st.push({ i });
}
}
while (!st.empty()) {
vector<int> top = st.top(); st.pop();
int leftlessindex = st.empty() ? -1 : st.top().back();
for (auto x : top) {
ret[x].first = leftlessindex;
ret[x].second = -1;
}
}
return ret;
}
vector<pair<int, int>> getNearf1(vector<int>& arr) {
vector<pair<int, int>> ret(arr.size());
stack<vector<int>> st;
for (int i = 0; i < arr.size(); i++) {
while (!(st.empty() || arr[i]*arr[i] > arr[st.top()[0]]* arr[st.top()[0]])) {
vector<int> top = st.top(); st.pop();
int leftlessindex = st.empty() ? -1 : st.top().back();
for (auto x : top) {
ret[x].first = leftlessindex;
ret[x].second = i;
}
}
if (!st.empty() && arr[i] == arr[st.top()[0]]) {
st.top().push_back(i);
} else {
st.push({ i });
}
}
while (!st.empty()) {
vector<int> top = st.top(); st.pop();
int leftlessindex = st.empty() ? -1 : st.top().back();
for (auto x : top) {
ret[x].first = leftlessindex;
ret[x].second = -1;
}
}
return ret;
}
};
int main() {
vector<int> arr = { 3,2,4,3,3,4,1,3,4,5, };
// 0 1 2 3 4 5 6 7 8 9
vector<pair<int, int>> ret = Solution().getNearf1(arr);
for (int i = 0; i < arr.size(); i++) {
cout << i << ":" << "[" << ret[i].first << "," << ret[i].second << "]" << endl;
}
}
求各个元素左边和右边的最近的大于(等于)的下标
只需要保证栈从栈底到栈顶是严格递减即可,其他逻辑是一样的。
单调栈的扩展
单调栈不止求最近值的大小,还可以是其他的性质,只需要满足栈底到栈顶维持这个性质的单调性即可,当加入的元素不能满足这个单调性,此时就可以依次最近的某个性质。
求各个元素左边和右边最近 平方数 小于(等于)的下标

vector<pair<int, int>> getNearf1(vector<int>& arr) {
vector<pair<int, int>> ret(arr.size());
stack<vector<int>> st;
for (int i = 0; i < arr.size(); i++) {
while (!(st.empty() || arr[i]*arr[i] > arr[st.top()[0]]* arr[st.top()[0]])) {
vector<int> top = st.top(); st.pop();
int leftlessindex = st.empty() ? -1 : st.top().back();
for (auto x : top) {
ret[x].first = leftlessindex;
ret[x].second = i;
}
}
if (!st.empty() && arr[i] == arr[st.top()[0]]) {
st.top().push_back(i);
} else {
st.push({ i });
}
}
while (!st.empty()) {
vector<int> top = st.top(); st.pop();
int leftlessindex = st.empty() ? -1 : st.top().back();
for (auto x : top) {
ret[x].first = leftlessindex;
ret[x].second = -1;
}
}
return ret;
}
求各个求各个元素左边最近大于等于右边最近大于的下标
class Solution {
public:
int getNeat_LeftHightEqual_RightHight(vector<int>& h) {
int n = h.size();
vector<pair<int, int>> map(n);
stack<vector<int>> st;
for (int i = 0; i < n; i++) {
while (!(st.empty() || h[i] < h[st.top()[0]])) {
vector<int> top = st.top();
st.pop();
int leftminindex = st.empty() ? -1 : st.top().back();
for (auto x : top) {
map[x].first = leftminindex;
map[x].second = i;
}
}
st.push({i});
}
while (!st.empty()) {
vector<int> top = st.top();
st.pop();
int leftminindex = st.empty() ? -1 : st.top().back();
for (auto x : top) {
map[x].first = leftminindex;
map[x].second = -1;
}
}
return ret;
}
};
结尾
最后,感谢您阅读我的文章,希望这些内容能够对您有所启发和帮助。如果您有任何问题或想要分享您的观点,请随时在评论区留言。
同时,不要忘记订阅我的博客以获取更多有趣的内容。在未来的文章中,我将继续探讨这个话题的不同方面,为您呈现更多深度和见解。
谢谢您的支持,期待与您在下一篇文章中再次相遇!
本文介绍了如何利用单调栈数据结构解决求解数组中每个元素左右两边最近小于等于的元素下标的算法,涉及两个方法:getNearLessEqual和getNearLess。关键在于维护栈的单调性,确保栈顶元素满足特定条件。
911

被折叠的 条评论
为什么被折叠?



