Opening the reading…
Opening the reading…
STACK › ADVANCE STACK PROBLEMS
Open — the attempt gate is not wired up yet
This editorial is meant to unlock after you have run the problem at least once, with the worked solution behind one further deliberate click. That needs per-learner unlock state nothing stores today, so for now the whole article is open.
Try it yourself first →Ignore parentheses for a moment. A flat expression can be evaluated by remembering two things: the result accumulated so far and the sign that belongs to the next number. When you finish reading a number, add sign times number to result. A plus sets sign to 1, and a minus sets it to -1. Spaces do not change either value.
Parentheses temporarily change the place where numbers are being added. When you read an opening parenthesis, save the outside result and sign, then start a fresh inner result at zero. When the closing parenthesis arrives, the inner result is complete: multiply it by the saved sign and add it to the saved result. The stack stores these saved pairs, one pair for each currently open parenthesis.
| MEASURE | BOUND | WHY |
|---|---|---|
| Time | O(n) | Each character is inspected once. Digits may update num, operators may flush one number, and parentheses perform constant-time stack work, so no character is rescanned. |
| Space | O(n) extra space | The returned integer is output and uses no counted storage. The stack holds one result-sign pair per open parenthesis; in the worst input shape, parentheses can be nested to depth proportional to n, so the working space is O(n). |
#include <cctype>
#include <stack>
#include <string>
using namespace std;
class Solution {
public:
int calculate(string s) {
stack<int> st;
int result = 0;
int sign = 1;
int num = 0;
for (char c : s) {
if (isdigit(static_cast<unsigned char>(c))) {
num = num * 10 + (c - '0');
} else if (c == '+' || c == '-') {
result += sign * num;
num = 0;
sign = (c == '+') ? 1 : -1;
} else if (c == '(') {
st.push(result);
st.push(sign);
result = 0;
sign = 1;
} else if (c == ')') {
result += sign * num;
num = 0;
result *= st.top();
st.pop();
result += st.top();
st.pop();
}
}
result += sign * num;
return result;
}
};The two pushes at an opening parenthesis deliberately use result first and sign second. The close operation therefore sees the sign at the top, applies it to the completed inner result, and then retrieves the saved outer result. Resetting result and sign after the push is equally important: without it, the inner expression would inherit terms that belong outside the parentheses.
You can replace the explicit stack with recursive calls. A parser evaluates the expression inside an opening parenthesis and returns when it reaches the matching close. The caller then treats that returned value like one number. This is not an asymptotic optimisation: the explicit stack becomes the runtime call stack, so both methods use O(n) extra space in the worst nesting depth.
#include <cctype>
#include <string>
using namespace std;
class Solution {
private:
int parse(const string& s, int& index) {
int result = 0;
int sign = 1;
while (index < static_cast<int>(s.size())) {
char c = s[index];
if (c == ' ') {
++index;
} else if (isdigit(static_cast<unsigned char>(c))) {
int num = 0;
while (index < static_cast<int>(s.size()) &&
isdigit(static_cast<unsigned char>(s[index]))) {
num = num * 10 + (s[index] - '0');
++index;
}
result += sign * num;
sign = 1;
} else if (c == '+') {
sign = 1;
++index;
} else if (c == '-') {
sign = -1;
++index;
} else if (c == '(') {
++index;
result += sign * parse(s, index);
sign = 1;
} else {
++index;
return result;
}
}
return result;
}
public:
int calculate(string s) {
int index = 0;
return parse(s, index);
}
};The recursive version buys a direct correspondence between nesting and function calls, which can make the parser easier to extend. The iterative version avoids dependence on the language call stack and keeps all unfinished expressions in visible storage. Choose recursion for the cleaner structural match; choose the explicit stack when input nesting may approach the stack limit.