Skip to content

Commit 6b03ead

Browse files
my (bad) solution to 1190 :(
😭
1 parent c5b8c2d commit 6b03ead

File tree

1 file changed

+79
-2
lines changed

1 file changed

+79
-2
lines changed

problems/1190/jeremymanning.md

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,88 @@
11
# [Problem 1190: Reverse Substrings Between Each Pair of Parentheses](https://leetcode.com/problems/reverse-substrings-between-each-pair-of-parentheses/description/?envType=daily-question)
22

33
## Initial thoughts (stream-of-consciousness)
4+
- The simplest solution would be to use recursion:
5+
- Start with `result = ''`
6+
- Append characters to `result` until if/when we encounter an open parenthesis (at position `i`)
7+
- If so, set `counter = 1`
8+
- Now continue to move forward through the string (starting at `i + 1`):
9+
- If we encounter an open parenthesis, `counter += 1`
10+
- If we encounter a closed parenthesis, `counter -= 1`
11+
- If we ever get to `counter == 0` (at position `j`):
12+
- set `result += reverseParenthesis(s[i + 1:j])[::-1]`
13+
- set `i = j + 1`
14+
- continue
15+
- Then once we run out of characters, return `result`
16+
- I can see that the recursive solution will "work," but it's inefficient. E.g., the string can be 2000 characters long, so if it's something like `s = (((((....((()))...)))))` we'll need to potentially recurse to a depth of up to 1000, which would be (a) memory inefficient (we have to copy all of the variables with each new recurse), and (b) potentially beyond the recursion limit.
17+
- Another approach would be to maintain two "result" strings-- one for the starting characters (moving from the beginning to the end) and the other for the ending characters (moving from the end to the beginning)
18+
- Or...maybe we can just use two indices (`i` moves from beginning to end and `j` moves from the end to the beginning)?
19+
- We could do something like:
20+
- Keep track of whether we need to reverse (parenthesis depth is odd) or not (parenthesis depth is even). Start with `reverse = False`, `i = 0`, `j = len(s) - 1`, `result = ''`,
21+
- While `i < j`:
22+
- simple case: we're at an even depth (`reverse` is `False`): just append each character in turn to `result` and increment `i` by 1 until we hit an open parenthesis
23+
- complicated: if we're at an odd depth, i think we need to do something like:
24+
- move `i` forward *and* `j` backwards, keep track of stuff in the forward direction in one variable and in the backwards direction in another variable. We'll want to prepend each new character `s[i]` to the forward direction string and append each new character `s[j]` to the backwards direction string
25+
- if we hit an open parenthesis in the forward direction we stop moving forward, and if we hit a backwards parenthesis in the backwards direction we stop moving backwards
26+
- to figure out: what do we *do* with those temporary strings...
27+
- I guess we could append the backwards direction string to `result` immediately...but what happens to the forward direction string 🤔? Kind of tricky!
28+
- Hmm...
29+
- Could we do an "in place" reverse?
30+
- Look for the outermost open parenthesis
31+
- Look for the matching close parenthesis
32+
- Keep the stuff outside those outermost parentheses
33+
- Remove the parentheses + reverse the stuff inside them (now the string shrinks in length by 2...maybe this isn't terrible?)
34+
- Would this work... 🤔...
35+
- Suppose we had something like `s = 'a(bc(de)fg)h'`. What happens?
36+
- We have parentheses:
37+
- `before = 'a'`; `after = 'h'`; `to_reverse = 'bc(de)fg`
38+
- Now set `s = before + to_reverse[::-1] + after` -- so `s` is now `'agf)ed(cbh'`...so clearly we'll need to match *both* open and closed parentheses. If the parentheses weren't guaranteed to be balanced, this would be a problem. Actually, maybe when we reverse things we can just flip the directions of the parentheses? That'd give us `'agf(ed)cbh'`...
39+
- There are still parentheses remaining, so now:
40+
- `before = 'agf'`; `after = 'cbh'`; `to_reverse = 'ed'`
41+
- Now we set `s = before + to_reverse[::-1].replace('(', '*').replace(')', '(').replace('*', ')') + after` (aside: this is a mess...), so `s = 'agfdecbh'`. Which seems...correct...
42+
- Is this efficient?
43+
- Potentially involves reshuffling stuff lots of times in memory, which seems sub-optimal, but maybe it's ok?
44+
- The solution is $O(np)$ where $n$ is the string length and $p$ is the number of parenthesis pairs. If $n = 2000, p = 1000$ that could be slow...although in that "worst case" the string would actually keep shrinking, so we'd probably get closer to something like $O(p \log n)$ runtime...
45+
- Another test case to consider: what happens if pairs of parentheses are side by side-- e.g., `s = 'ab(cd)ef(gh)'`. Then, actually, this solution won't work, because the "cd" open parenthesis will get paired with the "gh" closed parenthesis. So we might need to either manually track this or do something clever...
46+
- I'm about out of time for tonight, so I'm just going to try quickly implementing the recursive solution and see if it works...
447

548
## Refining the problem, round 2 thoughts
49+
- Any special cases to consider?
50+
- Eh....it's just inefficient. I don't think it'll be "wrong" per se. I'm guessing it'll time out on one of the test cases though.
651

752
## Attempted solution(s)
853
```python
9-
class Solution: # paste your code here!
10-
...
54+
class Solution:
55+
def reverseParentheses(self, s: str) -> str:
56+
def helper(s):
57+
result = ''
58+
i = 0
59+
while i < len(s):
60+
if s[i] != '(':
61+
result += s[i]
62+
else:
63+
depth = 1
64+
j = i + 1
65+
while j < len(s):
66+
if s[j] == '(':
67+
depth += 1
68+
elif s[j] == ')':
69+
depth -= 1
70+
71+
if depth == 0:
72+
result += helper(s[i + 1:j])[::-1]
73+
i = j
74+
break
75+
j += 1
76+
i += 1
77+
78+
return result
79+
80+
return helper(s)
1181
```
82+
- The given test cases pass
83+
- I don't have time to think up more clever test cases, so I'll just submit...
84+
85+
![Screenshot 2024-07-10 at 11 43 29 PM](https://github.com/ContextLab/leetcode-solutions/assets/9030494/21571097-ef6a-47d2-ad1f-d490187ad9bb)
86+
87+
Huh, I guess it worked!
88+

0 commit comments

Comments
 (0)