关键词:单调栈
【题目】一个整数数组 A,找到每个元素:右边第一个比我小的下标位置,没有则用 -1 表示。
输入:[5, 2]
输出:[1, -1]
解法:
class Solution {
vector<int> findRightSmall(vector<int> &A) {
if (A.empty()) {
return {};
}
// 结果数组
vector<int> ans(A.size());
// 注意,栈中的元素记录的是下标
stack<int> t;
for (size_t i = 0; i < A.size(); i++) {
const int x = A[i];
// 每个元素都向左遍历栈中的元素完成消除动作
while (!t.empty() && A[t.top()] > x) {
// 消除的时候,记录一下被谁消除了
ans[t.top()] = i;
// 消除时候,值更大的需要从栈中消失
t.pop();
}
// 剩下的入栈
t.push(i);
}
// 栈中剩下的元素,由于没有人能消除他们,因此,只能将结果设置为-1。
while (!t.empty()) {
ans[t.top()] = -1;
t.pop();
}
return ans;
}
};
变种一:右边第一个比我大
class Solution {
vector<int> findRightLarge(vector<int> &A) {
if (A.empty()) {
return {};
}
// 结果数组
vector<int> ans(A.size());
// 注意,栈中的元素记录的是下标
stack<int> t;
for (size_t i = 0; i < A.size(); i++) {
const int x = A[i];
// 每个元素都向左遍历栈中的元素完成消除动作
while (!t.empty() && A[t.top()] < x) {
// 消除的时候,记录一下被谁消除了
ans[t.top()] = i;
// 消除时候,值更大的需要从栈中消失
t.pop();
}
// 剩下的入栈
t.push(i);
}
// 栈中剩下的元素,由于没有人能消除他们,因此,只能将结果设置为-1。
while (!t.empty()) {
ans[t.top()] = -1;
t.pop();
}
return ans;
}
};
变种二:左边第一个比我大
class Solution {
public:
vector<int> findLeftLarge(vector<int>& A) {
if (A.empty()) {
return {};
}
const int N = A.size();
// 结果数组
vector<int> ans(N);
// 注意,栈中的元素记录的是下标
stack<int> t;
// 注意这里的遍历方向发生了变化,因为我们是要找到左边比我小的元素的位置
for (int i = N - 1; i >= 0; i--) {
const int x = A[i];
// 每个元素都遍历栈中的元素完成消除动作
// 这里是递减栈
// 如果发现进来的元素x与栈中元素相比
// 如果大于栈中的元素,那么要把栈中的元素弹出去
while (!t.empty() && A[t.top()] < x) {
// 消除的时候,记录一下被谁消除了
ans[t.top()] = i;
// 消除时候,值更大的需要从栈中消失
t.pop();
}
// 剩下的入栈
t.push(i);
}
// 栈中剩下的元素,由于没有人能消除他们,因此,只能将结果设置为-1。
while (!t.empty()) {
ans[t.top()] = -1;
t.pop();
}
return ans;
}
};
变种三:左边第一个比我小
class LeftSmall {
// 当我们要找左边比我小的元素的时候,需要用递增栈
public:
static vector<int> findLeftSmall(vector<int>& A) {
if (A.empty()) {
return {};
}
const int N = A.size();
// 结果数组
vector<int> ans(N);
// 注意,栈中的元素记录的是下标
stack<int> t;
// 注意这里的遍历方向发生了变化,因为我们是要找到左边比我小的元素的位置
for (int i = N - 1; i >= 0; i--) {
const int x = A[i];
// 每个元素都遍历栈中的元素完成消除动作
// 这里是递减栈
// 如果发现进来的元素x与栈中元素相比
// 如果大于栈中的元素,那么要把栈中的元素弹出去
while (!t.empty() && A[t.top()] > x) {
// 消除的时候,记录一下被谁消除了
ans[t.top()] = i;
// 消除时候,值更大的需要从栈中消失
t.pop();
}
// 剩下的入栈
t.push(i);
}
// 栈中剩下的元素,由于没有人能消除他们,因此,只能将结果设置为-1。
while (!t.empty()) {
ans[t.top()] = -1;
t.pop();
}
return ans;
}
};
单调栈解决数组中元素右侧特定条件索引问题
该博客介绍了如何使用单调栈解决数组中元素右侧第一个比其小或大的元素索引问题。提供了四种解法,包括原题及三种变种,详细解释了每种解法的思路和代码实现,涉及数据结构和算法的应用。

999

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



