关键词:单调栈
【题目】一个整数数组 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;
}
};