Matching / nesting (Stack Sub-pattern)
Openers wait on the stack until their closer arrives. The closer must match the top. Variants push indices (to delete unmatched ones) or whole saved levels (to decode nested repeats).
- ›
"valid parentheses", brackets of several types
- ›
"remove adjacent duplicates" (a char cancels the one before it)
- ›
"remove the minimum number of brackets"
- ›
nested repeats like
k[...]
The question is what you push: the character (just check it), the index (you'll delete it later), or a saved level (count, text) (you'll glue the inner result back on). For adjacent duplicates the answer string itself is the stack. (Minimum Remove can also be done with two counter passes — left→right drops extra ), right→left drops extra ( — also O(N); the stack of indices is the pattern version.)
Questions
ordered from “learn the idea” to “recognise it without help”- 1Valid ParenthesesWalkthroughEasyBasic Anchor·LeetCode #20
- 2Remove All Adjacent Duplicates In StringWalkthroughEasyBasic Reinforcement·LeetCode #1047
- 3Minimum Remove to Make Valid ParenthesesWalkthroughMediumSlight Variation·LeetCode #1249
- 4Decode StringWalkthroughMediumMedium·LeetCode #394
Template
// Do the brackets match? Openers wait on the stack; each closer must match the top.
bool isValid(string s) {
stack<char> st;
for (char c : s) {
if (c == '(' || c == '[' || c == '{') {
st.push(c); // opener: wait for its partner
} else {
if (st.empty()) return false; // closer with nothing open
char open = st.top(); st.pop();
if ((c == ')' && open != '(') ||
(c == ']' && open != '[') ||
(c == '}' && open != '{')) return false; // wrong partner
}
}
return st.empty(); // something left open → invalid
}