Skip to content

Commit 2862b50

Browse files
committed
added minimum element from stack at constant time
1 parent c2adc3b commit 2862b50

File tree

2 files changed

+141
-1
lines changed

2 files changed

+141
-1
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
"xtr1common": "cpp",
8787
"xtree": "cpp",
8888
"xutility": "cpp",
89-
"climits": "cpp"
89+
"climits": "cpp",
90+
"cassert": "cpp"
9091
}
9192
}
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/**
2+
* @author [S-M-J-I](https://github.com/S-M-J-I)
3+
* @file
4+
*
5+
* Implementation of stack that retrieves the minimum element in constant time.
6+
* (https://www.baeldung.com/cs/stack-constant-time)
7+
*
8+
* @details
9+
* The MinStack data structure keeps track of the minimum element present in a
10+
* stack and retrieves them at O(1) time.
11+
*/
12+
#include <cassert>
13+
#include <iostream>
14+
#include <stack>
15+
#include <stdexcept>
16+
17+
/**
18+
* @namespace
19+
* @brief data_structures
20+
*/
21+
namespace data_structures {
22+
/**
23+
* @brief Class representation of a the minimum stack
24+
*/
25+
class MinStack {
26+
private:
27+
/**
28+
* the mainStack keeps track of the elements in the stack
29+
* the minStack keeps track of the minimum elements present in the stack so
30+
* far
31+
*/
32+
std::stack<int> mainStack, minStack;
33+
34+
public:
35+
/**
36+
* @brief Constructs a new MinStack object to initialize the mainStack and
37+
* the minStack
38+
*/
39+
MinStack() = default;
40+
41+
/**
42+
* @brief Pushes the data in the stack. If the data is the minimum element
43+
* so far, then pushes it into the minStack to keep track of it.
44+
* @param data The element to be pushed to the stack
45+
*/
46+
void push(int data) {
47+
if (mainStack.empty()) {
48+
mainStack.push(data);
49+
minStack.push(data);
50+
return;
51+
}
52+
53+
mainStack.push(data);
54+
if (data < minStack.top()) {
55+
minStack.push(data);
56+
}
57+
}
58+
59+
/**
60+
* @brief Pops the data from the stack. If the data that is removed is the
61+
* minimum element, then remove it from the minStack as well.
62+
* @throws std::out_of_range if the stack is empty
63+
*/
64+
void pop() {
65+
if (mainStack.empty()) {
66+
throw std::out_of_range("Stack underflow");
67+
}
68+
69+
int top_ele = mainStack.top();
70+
mainStack.pop();
71+
if (top_ele == minStack.top()) {
72+
minStack.pop();
73+
}
74+
}
75+
/**
76+
* @brief Gets the minimum element of the stack
77+
* @return The minimum element at the top of the minStack
78+
* @throws std::out_of_range if the minStack is empty
79+
*/
80+
int get_min() {
81+
if (minStack.empty()) {
82+
throw std::out_of_range("Stack underflow");
83+
}
84+
return minStack.top();
85+
}
86+
};
87+
} // namespace data_structures
88+
89+
/**
90+
* @brief test cases
91+
*/
92+
static void test() {
93+
data_structures::MinStack minStack;
94+
95+
// Test pushing elements and checking the minimum element
96+
minStack.push(10);
97+
assert(minStack.get_min() == 10);
98+
99+
minStack.push(20);
100+
assert(minStack.get_min() == 10);
101+
102+
minStack.push(30);
103+
minStack.push(4);
104+
minStack.push(1);
105+
assert(minStack.get_min() == 1);
106+
107+
// Test popping elements
108+
minStack.pop();
109+
assert(minStack.get_min() == 4);
110+
minStack.pop();
111+
assert(minStack.get_min() == 10);
112+
113+
// Test minStack underflow
114+
try {
115+
minStack.pop();
116+
minStack.pop();
117+
minStack.pop();
118+
minStack.pop();
119+
} catch (const std::out_of_range& e) {
120+
assert(std::string(e.what()) == "Stack underflow");
121+
}
122+
123+
// Try to get the minimum from empty stack
124+
try {
125+
minStack.get_min();
126+
} catch (const std::out_of_range& e) {
127+
assert(std::string(e.what()) == "Stack underflow");
128+
}
129+
}
130+
131+
/**
132+
* @brief Main function
133+
* @returns 0 on exit
134+
*/
135+
int main() {
136+
test(); // run self-test implementations
137+
std::cout << "All tests passed!" << std::endl;
138+
return 0;
139+
}

0 commit comments

Comments
 (0)