From 58a16416e44ef2b9ebe3dcbe95d6cd923bd79626 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 27 Sep 2026 05:31:55 +0000 Subject: [PATCH] feat: add solution for 1190. Reverse Substrings Between Each Pair of Parentheses --- .../analysis.md | 58 +++++++++++++++++++ .../problem.md | 58 +++++++++++++++++++ .../solution_daily_20260927.go | 33 +++++++++++ .../solution_daily_20260927_test.go | 31 ++++++++++ 4 files changed, 180 insertions(+) create mode 100644 problems/1190-reverse-substrings-between-each-pair-of-parentheses/analysis.md create mode 100644 problems/1190-reverse-substrings-between-each-pair-of-parentheses/problem.md create mode 100644 problems/1190-reverse-substrings-between-each-pair-of-parentheses/solution_daily_20260927.go create mode 100644 problems/1190-reverse-substrings-between-each-pair-of-parentheses/solution_daily_20260927_test.go diff --git a/problems/1190-reverse-substrings-between-each-pair-of-parentheses/analysis.md b/problems/1190-reverse-substrings-between-each-pair-of-parentheses/analysis.md new file mode 100644 index 0000000..609033f --- /dev/null +++ b/problems/1190-reverse-substrings-between-each-pair-of-parentheses/analysis.md @@ -0,0 +1,58 @@ +# 1190. Reverse Substrings Between Each Pair of Parentheses + +[LeetCode Link](https://leetcode.com/problems/reverse-substrings-between-each-pair-of-parentheses/) + +Difficulty: Medium +Topics: String, Stack, Bracket Sequences +Acceptance Rate: 72.9% + +## Hints + +### Hint 1 + +Whenever you see nested, balanced brackets that must be processed "innermost first", think about a **stack**. Matching each `(` with its `)` is the classic stack job. + +### Hint 2 + +A straightforward approach: keep a stack of partially built strings (or indices). When you hit `)`, reverse the segment since the most recent `(`. This is O(n²) in the worst case but passes easily for n ≤ 2000. Can you avoid doing the reversals physically at all? + +### Hint 3 + +Precompute `pair[i]` — the index of the matching parenthesis for every bracket (one stack pass). Now walk the string with a pointer `i` and a direction `d = +1`. When you land on a parenthesis, **jump to its partner and flip the direction** (`i = pair[i]; d = -d`), then keep stepping. Letters are appended as you visit them. Each character is visited exactly once, so the walk is O(n). + +## Approach + +**Why the "wormhole" trick works:** Reversing a segment means reading it from right to left. When we reach an opening `(` while moving forward, the segment inside needs to be read backwards — so we teleport to the matching `)` and start moving left. Nested pairs inside are handled the same way: hitting a bracket while moving left teleports us to its partner and flips direction again (two reversals cancel out). When we finally reach the original `(` again from the inside, we teleport back to the `)` and continue forward past it. + +**Algorithm:** + +1. **Pair brackets.** Scan `s` with a stack of indices. Push on `(`; on `)`, pop `j` and set `pair[i] = j`, `pair[j] = i`. +2. **Walk.** Start at `i = 0`, `d = 1`. While `0 <= i < n`: + - If `s[i]` is a bracket: `i = pair[i]`, `d = -d`. + - Otherwise append `s[i]` to the result. + - Then `i += d`. +3. Return the result. + +**Example:** `s = "(u(love)i)"` (indices 0..9, pairs: 0↔9, 2↔7) + +- i=0 `(` → jump to 9, d=-1 → i=8 `i` → append "i" +- i=7 `)` → jump to 2, d=+1 → i=3..6 → append "love" +- i=7 `)` → jump to 2, d=-1 → i=1 `u` → append "u" +- i=0 `(` → jump to 9, d=+1 → i=10, stop. + +Result: `"iloveu"` ✓ + +A simpler stack-of-builders solution (reverse on each `)`) is also perfectly acceptable in an interview; mention the O(n) wormhole idea as the optimization. + +## Complexity Analysis + +Time Complexity: O(n) — one pass to pair brackets, one walk visiting each character a bounded number of times. +Space Complexity: O(n) — the `pair` array, the index stack, and the output buffer. + +## Edge Cases + +- **No parentheses** (`"abc"`): the string is returned unchanged. +- **Empty parentheses** (`"()"` or `"a()b"`): contribute nothing; the walk jumps in and straight back out. +- **Deep nesting** (`"((ab))"`): even number of reversals cancels out → `"ab"`. +- **Adjacent groups** (`"(ab)(cd)"`): each group is reversed independently → `"badc"`. +- **Letters outside brackets** (`"a(bc)d"`): only the inner segment is reversed → `"acbd"`. diff --git a/problems/1190-reverse-substrings-between-each-pair-of-parentheses/problem.md b/problems/1190-reverse-substrings-between-each-pair-of-parentheses/problem.md new file mode 100644 index 0000000..a715ffe --- /dev/null +++ b/problems/1190-reverse-substrings-between-each-pair-of-parentheses/problem.md @@ -0,0 +1,58 @@ +--- +number: "1190" +frontend_id: "1190" +title: "Reverse Substrings Between Each Pair of Parentheses" +slug: "reverse-substrings-between-each-pair-of-parentheses" +difficulty: "Medium" +topics: + - "String" + - "Stack" + - "Bracket Sequences" +acceptance_rate: 7290.8 +is_premium: false +created_at: "2026-09-27T05:31:01.909324+00:00" +fetched_at: "2026-09-27T05:31:01.909324+00:00" +link: "https://leetcode.com/problems/reverse-substrings-between-each-pair-of-parentheses/" +date: "2026-09-27" +--- + +# 1190. Reverse Substrings Between Each Pair of Parentheses + +You are given a string `s` that consists of lower case English letters and brackets. + +Reverse the strings in each pair of matching parentheses, starting from the innermost one. + +Your result should **not** contain any brackets. + + + +**Example 1:** + + + **Input:** s = "(abcd)" + **Output:** "dcba" + + +**Example 2:** + + + **Input:** s = "(u(love)i)" + **Output:** "iloveu" + **Explanation:** The substring "love" is reversed first, then the whole string is reversed. + + +**Example 3:** + + + **Input:** s = "(ed(et(oc))el)" + **Output:** "leetcode" + **Explanation:** First, we reverse the substring "oc", then "etco", and finally, the whole string. + + + + +**Constraints:** + + * `1 <= s.length <= 2000` + * `s` only contains lower case English characters and parentheses. + * It is guaranteed that all parentheses are balanced. diff --git a/problems/1190-reverse-substrings-between-each-pair-of-parentheses/solution_daily_20260927.go b/problems/1190-reverse-substrings-between-each-pair-of-parentheses/solution_daily_20260927.go new file mode 100644 index 0000000..053b5e8 --- /dev/null +++ b/problems/1190-reverse-substrings-between-each-pair-of-parentheses/solution_daily_20260927.go @@ -0,0 +1,33 @@ +package main + +// Approach: "wormhole" traversal. +// First pair every '(' with its matching ')' using a stack of indices. +// Then walk the string: on a bracket, jump to its partner and flip the +// walking direction; on a letter, append it. Each segment inside a pair is +// thus read in reverse, and nested reversals cancel naturally. O(n) time. +func reverseParentheses(s string) string { + n := len(s) + pair := make([]int, n) + stack := make([]int, 0, n) + for i := 0; i < n; i++ { + switch s[i] { + case '(': + stack = append(stack, i) + case ')': + j := stack[len(stack)-1] + stack = stack[:len(stack)-1] + pair[i], pair[j] = j, i + } + } + + res := make([]byte, 0, n) + for i, d := 0, 1; i >= 0 && i < n; i += d { + if s[i] == '(' || s[i] == ')' { + i = pair[i] + d = -d + } else { + res = append(res, s[i]) + } + } + return string(res) +} diff --git a/problems/1190-reverse-substrings-between-each-pair-of-parentheses/solution_daily_20260927_test.go b/problems/1190-reverse-substrings-between-each-pair-of-parentheses/solution_daily_20260927_test.go new file mode 100644 index 0000000..3a49f08 --- /dev/null +++ b/problems/1190-reverse-substrings-between-each-pair-of-parentheses/solution_daily_20260927_test.go @@ -0,0 +1,31 @@ +package main + +import "testing" + +func TestReverseParentheses(t *testing.T) { + tests := []struct { + name string + s string + expected string + }{ + {"example 1: single pair", "(abcd)", "dcba"}, + {"example 2: two nested levels", "(u(love)i)", "iloveu"}, + {"example 3: three nested levels", "(ed(et(oc))el)", "leetcode"}, + {"edge case: no parentheses", "abc", "abc"}, + {"edge case: empty parentheses", "a()b", "ab"}, + {"edge case: only empty parentheses", "()", ""}, + {"edge case: double nesting cancels", "((ab))", "ab"}, + {"edge case: adjacent groups", "(ab)(cd)", "badc"}, + {"edge case: letters outside brackets", "a(bc)d", "acbd"}, + {"edge case: single character", "a", "a"}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := reverseParentheses(tt.s) + if result != tt.expected { + t.Errorf("got %q, want %q", result, tt.expected) + } + }) + } +}