Stacks & Their Applications
স্ট্যাক ও তার ব্যবহার
1. LIFO — Last In, First Out
A stack only allows access to the most recently added element. Three operations:
push(x) adds, pop() removes the top, top() peeks. All O(1).
Think of a stack of plates — you can only take from the top.
2. Implementing a Stack
std::stack wraps std::deque, but we'll build one over std::vector to see the inside.
#include <bits/stdc++.h>
using namespace std;
template<class T>
struct Stack {
vector<T> v;
void push(const T& x) { v.push_back(x); }
void pop() { v.pop_back(); }
T& top() { return v.back(); }
bool empty() const { return v.empty(); }
size_t size() const { return v.size(); }
};
int main() {
Stack<int> s;
for (int x : {10, 20, 30, 40}) s.push(x);
while (!s.empty()) {
cout << s.top() << " ";
s.pop();
}
}
Output: 40 30 20 10 — reverse insertion order.
3. Killer App #1: Balanced Parentheses
Every (, {, [ goes on the stack. Each closing bracket must match the top. Empty stack at the end ⇒ balanced.
#include <bits/stdc++.h>
using namespace std;
bool balanced(const string& s) {
stack<char> st;
unordered_map<char,char> mate = { {')','('}, {']','['}, {'}','{'} };
for (char c : s) {
if (c == '(' || c == '[' || c == '{') st.push(c);
else if (mate.count(c)) {
if (st.empty() || st.top() != mate[c]) return false;
st.pop();
}
}
return st.empty();
}
int main() {
for (string t : {"({[]})", "(([", "[(])", ""}) {
cout << "\"" << t << "\" → " << (balanced(t) ? "OK" : "NO") << "\n";
}
}
4. Killer App #2: Monotonic Stack — Next Greater Element
For each element, find the next greater element to its right in O(n). Trick: keep a decreasing stack of indices. When the current element exceeds the index on top, that top found its answer.
5. Other Classic Stack Applications
| Problem | Stack idea |
|---|---|
| Infix → Postfix (Shunting-yard) | Operator stack with precedence comparison |
| Evaluate Postfix | Operand stack — pop two, apply op, push back |
| Function call stack | Each call pushes a frame; return pops |
| Editor undo / browser back | Push every action; pop to undo |
| DFS on graphs | Implicit recursive stack OR explicit std::stack |
| Largest Rectangle in Histogram | Monotonic increasing stack of bar indices |
6. Practice Problems
-
Find the next greater element for every entry of an array, using a monotonic stack in O(n).প্রতিটি element-এর পরের বড় element O(n)-এ বের করুন।
✨ Show Answer (উত্তর দেখুন)
a1.cpp#include <bits/stdc++.h> using namespace std; int main() { vector<int> a = {2, 1, 2, 4, 3}; int n = a.size(); vector<int> ans(n, -1); stack<int> st; for (int i = 0; i < n; i++) { while (!st.empty() && a[st.top()] < a[i]) { ans[st.top()] = a[i]; st.pop(); } st.push(i); } for (int x : ans) cout << x << " "; } -
Evaluate a postfix expression like
"3 4 + 5 *".postfix expression evaluate করুন।✨ Show Answer (উত্তর দেখুন)
a2.cpp#include <bits/stdc++.h> using namespace std; int main() { string e = "3 4 + 5 *"; stack<long long> st; stringstream ss(e); string tok; while (ss >> tok) { if (isdigit(tok[0])) st.push(stoll(tok)); else { long long b = st.top(); st.pop(); long long a = st.top(); st.pop(); if (tok == "+") st.push(a+b); else if (tok == "-") st.push(a-b); else if (tok == "*") st.push(a*b); else st.push(a/b); } } cout << st.top(); } -
Sort a stack using only one extra stack (no other arrays).শুধু একটি অতিরিক্ত stack ব্যবহার করে একটি stack sort করুন।
✨ Show Answer (উত্তর দেখুন)
a3.cpp#include <bits/stdc++.h> using namespace std; int main() { stack<int> in, out; for (int x : {3, 1, 4, 1, 5, 9, 2, 6}) in.push(x); while (!in.empty()) { int t = in.top(); in.pop(); while (!out.empty() && out.top() > t) { in.push(out.top()); out.pop(); } out.push(t); } while (!out.empty()) { cout << out.top() << " "; out.pop(); } } -
Implement a Min-Stack with O(1)
getMin().O(1)-এ min দেওয়া Min-Stack implement করুন।✨ Show Answer (উত্তর দেখুন)
a4.cpp#include <bits/stdc++.h> using namespace std; struct MinStack { stack<pair<int,int>> st; // (val, currentMin) void push(int x) { int m = st.empty() ? x : min(x, st.top().second); st.push({x, m}); } void pop() { st.pop(); } int top() { return st.top().first; } int getMin() { return st.top().second; } }; int main() { MinStack ms; for (int x : {5, 3, 7, 2, 8}) ms.push(x); cout << "min = " << ms.getMin(); } -
Largest rectangle in a histogram (O(n) with monotonic stack).Histogram-এ সবচেয়ে বড় rectangle — O(n) monotonic stack দিয়ে।
✨ Show Answer (উত্তর দেখুন)
a5.cpp#include <bits/stdc++.h> using namespace std; int main() { vector<int> h = {2,1,5,6,2,3}; h.push_back(0); stack<int> st; int best = 0; for (int i = 0; i < (int)h.size(); i++) { while (!st.empty() && h[st.top()] > h[i]) { int top = st.top(); st.pop(); int w = st.empty() ? i : i - st.top() - 1; best = max(best, h[top] * w); } st.push(i); } cout << best; } -
Daily temperatures: for each day, how many days until a warmer one?প্রতিটি দিনের জন্য — পরের warmer দিন কতদিন পর?
✨ Show Answer (উত্তর দেখুন)
a6.cpp#include <bits/stdc++.h> using namespace std; int main() { vector<int> t = {73,74,75,71,69,72,76,73}; vector<int> ans(t.size(), 0); stack<int> st; for (int i = 0; i < (int)t.size(); i++) { while (!st.empty() && t[st.top()] < t[i]) { ans[st.top()] = i - st.top(); st.pop(); } st.push(i); } for (int x : ans) cout << x << " "; } -
Determine if a sequence of pushes (1..n in order) and pops can produce a given output sequence.push order 1..n দিয়ে — দেওয়া pop order সম্ভব কিনা যাচাই করুন।
✨ Show Answer (উত্তর দেখুন)
a7.cpp#include <bits/stdc++.h> using namespace std; int main() { vector<int> out = {4,5,3,2,1}; int n = out.size(), nxt = 1, j = 0; stack<int> st; while (j < n) { if (!st.empty() && st.top() == out[j]) { st.pop(); j++; } else if (nxt <= n) { st.push(nxt++); } else break; } cout << (j == n ? "YES" : "NO"); }
Summary — Module 09
A stack is just push / pop / top, but it powers parsers, compilers,
DFS, undo systems, and a whole family of monotonic-stack tricks for "next greater"
problems. The pattern: when a single direction matters, reach for a stack first.