模版
//以下所有将b[i]=q.top().second改为b[i]=q.top().first 即可得到元素的值而不是坐标。
//n为数组规模,默认下标从1开始
//数组a为原数组
//数组b为查找到的坐标(元素值)
void findRMin(int n,int a[],int b[]) //寻找右边第一个比自己小的元素的坐标
{
stack<pair<int,int>> q;
for (int i=n;i>=1;i--)
{
while (!q.empty()&&a[i]<=q.top().first)
q.pop();
if (q.empty()) b[i]=0;
else b[i]=q.top().second;
q.push(make_pair(a[i],i));
}
}
void findLMin(int n,int a[],int b[]) //寻找左边第一个比自己小的元素的坐标
{
stack<pair<int,int>> q;
for (int i=1;i<=n;i++)
{
while (!q.empty()&&a[i]<=q.top().first)
q.pop();
if (q.empty()) b[i]=0;
else b[i]=q.top().second;
q.push(make_pair(a[i],i));
}
}
void findRMax(int n,int a[],int b[]) //寻找右边第一个比自己大的元素的坐标
{
stack<pair<int,int>> q;
for (int i=n;i>=1;i--)
{
while (!q.empty()&&a[i]>=q.top().first)
q.pop();
if (q.empty()) b[i]=0;
else b[i]=q.top().second;
q.push(make_pair(a[i],i));
}
}
void findLMax(int n,int a[],int b[]) //寻找左边第一个比自己大的元素的坐标
{
stack<pair<int,int>> q;
for (int i=1;i<=n;i++)
{
while (!q.empty()&&a[i]>=q.top().first)
q.pop();
if (q.empty()) b[i]=0;
else b[i]=q.top().second;
q.push(make_pair(a[i],i));
}
}
解释
以寻找右边第一个比自己小的元素的坐标为例,从最后一个元素开始从右往左遍历,栈q中按照从顶到底降序存储。
第一个while循环会弹出栈中所有大于当前元素a[i]的元素,直到找到比自己还小的元素,这使得栈中的所有元素都比a[i]小。
被弹出元素因为其大于当前元素a[i],所以对于a[i]左边的元素来说,被弹出元素不可能为第一个小于的元素,所以被弹出。
随后根据栈中是否有元素来判断右边是否有元素小于它,如果为空则没有,不为空则栈顶端的元素是第一个小于它的元素。
随后将元素a[i]和坐标i压入栈中。
Comments | NOTHING