
LeetCode 1190 Reverse Substrings Between Each Pair of Parentheses – Java Solution & Explanation
IntroductionLeetCode 1190 – Reverse Substrings Between Each Pair of Parentheses is a string manipulation problem that requires reversing the substring inside every matching pair of parentheses.The important part is that reversals must happen from the innermost parentheses outward.For example:(u(love)i)The substring love is reversed first:(u(evol)i)Then the complete content inside the outer parentheses is reversed, producing:iloveuThe final answer should contain only the letters. All parentheses must be removed.A stack is useful here because it allows the opening parenthesis of the current substring to be tracked until its matching closing parenthesis is encountered.ProblemQuestion Link-: Reverse Substrings Between Each Pair of ParenthesesGiven a string s containing lowercase English letters and parentheses, reverse the strings inside each pair of matching parentheses, starting from the innermost pair.Return the resulting string without any parentheses.ExampleInput:s = "(u(love)i)"Output:"iloveu"Another example:Input:s = "(ed(et(oc))el)"Output:"leetcode"ApproachThe key observation is that when a closing parenthesis ) is encountered, the substring belonging to the most recently opened parenthesis needs to be reversed first.This naturally matches the behavior of a stack.Step 1: Store opening parenthesesWhenever ( is encountered, its index is pushed onto the stack.For example:(ed(et(oc))el)When reaching nested opening parentheses, the stack stores their positions.The most recently added opening parenthesis belongs to the innermost substring.Step 2: Process a closing parenthesisWhen ) is encountered:Get the index of the matching ( from the top of the stack.Reverse the characters between those two parentheses.Remove the opening parenthesis index from the stack.For example:(oc)When ) is reached, oc is reversed:coThe same process then happens for the next outer pair.Step 3: Remove the parenthesesAfter all reversals are complete, the character array still contains ( and ).The final traversal simply collects all characters except the parentheses.Java SolutionThe following solution uses a Stack<Integer> to keep track of opening-parenthesis positions and a character array so that the reversals can be performed directly on the string representation.class Solution { public void rev(char[] s, int en, int st) { String rev = ""; for (int i = en; i >= st; i--) { rev += s[i]; } int co = 0; for (int i = st; i <= en; i++) { s[i] = rev.charAt(co); co++; } } public String reverseParentheses(String s) { Stack<Integer> st = new Stack<>(); char[] sa = s.toCharArray(); for (int i = 0; i < sa.length; i++) { if (sa[i] == '(') { st.push(i); } if (sa[i] == ')') { int star = st.peek(); rev(sa, i, star + 1); st.pop(); } } String an = ""; for (int i = 0; i < sa.length; i++) { if (sa[i] != ')' && sa[i] != '(') { an += sa[i]; } } return an; }}How the Code Worksrev() methodThe rev() method receives:s → character arrayen → ending indexst → starting indexIt first builds the reversed substring:for (int i = en; i >= st; i--) { rev += s[i];}Then the reversed characters are copied back into the original character array:for (int i = st; i <= en; i++) { s[i] = rev.charAt(co); co++;}This changes the substring directly inside the character array.Stack processingThe main method scans the string from left to right.When an opening parenthesis is found:if (sa[i] == '(') { st.push(i);}Its index is stored in the stack.When a closing parenthesis is found:if (sa[i] == ')') { int star = st.peek(); rev(sa, i, star + 1); st.pop();}The top of the stack gives the matching opening parenthesis.The substring between them is reversed, and then the opening parenthesis is removed from the stack.This automatically processes nested parentheses from the inside out.Dry RunConsider:s = "(u(love)i)"Initial character array:(u(love)i)1. First (Its index is pushed onto the stack.Stack:[0]2. Second (The opening parenthesis before love is pushed.Stack:[0, 2]3. First )The top of the stack is index 2.The substring between index 3 and 6 is:loveReverse it:evolNow the string is effectively:(u(evol)i)The inner opening parenthesis is removed from the stack.Stack:[0]4. Final )The remaining opening parenthesis corresponds to the outer substring.Its contents are now:uevoliReverse it:iloveuFinally, the parentheses are removed.Result:iloveuWhy a Stack WorksThe problem specifically says to process the innermost parentheses first.A stack follows Last In, First Out (LIFO).For:(ed(et(oc))el)the opening parentheses are encountered in order:(((The last opening parenthesis belongs to:(oc)Therefore, it must be processed first.The stack gives exactly this behavior:Last opened ↓ (oc) ↓ (etco) ↓(edoc...el)This is why a stack is a natural data structure for this problem.Complexity AnalysisLet n be the length of the input string.The stack operations themselves take O(n) time.However, the actual reversal is performed every time a closing parenthesis is encountered. In the provided implementation, the rev() method also builds a temporary String using repeated concatenation.Therefore, the worst-case time complexity of this implementation can reach O(n²).The final construction also uses:an += sa[i];Repeated string concatenation can additionally introduce quadratic behavior in Java.Time ComplexityO(n²) worst caseSpace ComplexityO(n)The stack and character array require linear auxiliary space.A Useful OptimizationThe overall idea is correct, but two parts of the implementation can be improved:String rev = "";andan += sa[i];Since Java String objects are immutable, repeated concatenation can create many intermediate strings.A StringBuilder is generally more appropriate for repeated character construction.The core stack-based idea, however, remains the same.Interview TipWhen a string problem involves nested structures, ask whether the processing order follows the structure of a stack.For parentheses:((()))the last opened section is the first one that must be completed.That is a strong signal for using a stack.A useful pattern to remember is:Opening bracket → push its positionClosing bracket → use the latest opening positionProcess inner section → popRecognizing this pattern can make similar nested-string and bracket problems much easier to approach.ConclusionLeetCode 1190 demonstrates how a simple stack can handle nested string operations efficiently at the algorithmic level.The main idea is to store the positions of opening parentheses and, whenever a closing parenthesis appears, reverse the substring associated with the most recently opened pair.The important pattern is:Opening parenthesis → push indexClosing parenthesis → reverse current substring → popFinal pass → remove parenthesesThis approach provides a straightforward way to process nested parentheses from the inside out while keeping the implementation relatively simple in Java.







