Skip to content

Solution #1021 - Abdul Wahab - 13/07/2025 #60

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# 1021. Remove Outermost Parentheses

**Difficulty:** *Easy*
**Category:** *Strings, Stack, Greedy*
**Leetcode Link:** [Problem Link](https://leetcode.com/problems/remove-outermost-parentheses/)

---

## 📝 Introduction

*Given a valid parentheses string, the task is to remove the outermost parentheses of every primitive substring. A primitive string is a non-empty valid parentheses string that cannot be split further into valid parts.*

---

## 💡 Approach & Key Insights

*Each primitive parentheses string is balanced and starts/ends with outermost parentheses. If we track the nesting level using a counter, we can easily identify the start and end of each primitive and skip appending the outermost layer.*

---

## 🛠️ Breakdown of Approaches

### 1️⃣ Brute Force / Naive Approach

- **Explanation:** *Use a stack to build substrings for each primitive, detect primitives by ensuring stack becomes empty, then remove the first and last characters.*
- **Time Complexity:** *O(n²) - Substring operations inside loop.*
- **Space Complexity:** *O(n) - For temporary stack and result string.*
- **Example/Dry Run:**

Example input: "(()())(())"
Step 1 → Extract primitives: "(()())", "(())"
Step 2 → Remove outermost: "()()", "()"
Step 3 → Output: "()()()"

### 2️⃣ Optimized Approach

- **Explanation:** *Use a counter to track the nesting depth. While iterating, append characters only if they’re not the outermost (i.e., depth > 1 before ‘)’ or after ‘(’).*
- **Time Complexity:** *O(n) - Single pass over string.*
- **Space Complexity:** *O(n) - For output string.*
- **Example/Dry Run:**

Example input: "(()())(())"
Step 1 → Traverse:
- ‘(’: depth becomes 1 → don’t add
- ‘(’: depth becomes 2 → add ‘(’
- ‘)’: depth becomes 1 → add ‘)’
- ‘)’: depth becomes 0 → don’t add
... and so on
Output: "()()()"

---

## 📊 Complexity Analysis

| Approach | Time Complexity | Space Complexity |
| ------------- | --------------- | ---------------- |
| Brute Force | O(n²) | O(n) |
| Optimized | O(n) | O(n) |

---

## 📉 Optimization Ideas

*The optimized solution is already linear in time and space. Further improvement would require in-place modification or custom output building if language permits.*

---

## 📌 Example Walkthroughs & Dry Runs

```plaintext
Example:
Input: "(()())(())(()(()))"
Process:
Primitive 1: "(()())" → Output: "()()"
Primitive 2: "(())" → Output: "()"
Primitive 3: "(()(()))" → Output: "()(())"
Final Output: "()()()()(())"
```

---

## 🔗 Additional Resources

- [Stack Data Structure](https://en.wikipedia.org/wiki/Stack_(abstract_data_type))
- [Valid Parentheses Leetcode](https://leetcode.com/problems/valid-parentheses/)

---

Author: Abdul Wahab
Date: 19/07/2025
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class Solution {
public:
string removeOuterParentheses(string s) {
string res;
int balance = 0, start = 0;
for (int i = 0; i < s.length(); ++i) {
if (s[i] == '(') balance++;
else balance--;
if (balance == 0) {
res += s.substr(start + 1, i - start - 1);
start = i + 1;
}
}
return res;
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class Solution:
def removeOuterParentheses(self, s: str) -> str:
res = []
balance = 0
start = 0

for i, ch in enumerate(s):
if ch == '(':
balance += 1
else:
balance -= 1
if balance == 0:
res.append(s[start + 1:i])
start = i + 1
return ''.join(res)