Problem
Write a function that reverses characters in (possibly nested) parentheses in the input string.
Input strings will always be well-formed with matching ()s.
For
inputString = "(bar)", the output should besolution(inputString) = "rab";For
inputString = "koo(bar)baz", the output should besolution(inputString) = "zoorabbaz";For
inputString = "koo(bar)baz(blim)", the output should besolution(inputString) = "zoorabbazmilb";For
inputString = "koo(bar(baz))blim", the output should besolution(inputString) = "zoobazrabblim".
Because"koo(bar(baz))blim"becomes"koo(barzab)blim"and then"zoobazrabblim".[input] string inputString
A string consisting of lowercase English letters and the characters
(and). It is guaranteed that all parentheses ininputStringform a regular bracket sequence.Guaranteed constraints:
0 ≤ inputString.length ≤ 50.[output] string
Return
inputString, with all the characters that were in parentheses reversed.
Solution
Step 1
Two variables are created, stack and tmp. stack is a slice of bytes with a length of 0, but with a capacity equal to the length of the input string s. tmp is also a slice of bytes with a length of 0 and capacity equal to the length of the input string.
package main
import (
"testing"
)
func solution(s string) string {
stack, tmp := make([]byte, 0, len(s)), make([]byte, 0, len(s))
for i := range s {
if s[i] == ')' {
i := len(stack) - 1
tmp = tmp[:0]
for ; stack[i] != '('; i-- {
tmp = append(tmp, stack[i])
}
stack = append(stack[:i], tmp...)
} else {
stack = append(stack, s[i])
}
}
return string(stack)
}
func TestReverseInParentheses(t *testing.T) {
tests := []struct {
input string
want string
}{
{"(bar)", "rab"},
{"foo(bar(baz))blim", "foobazrabblim"},
}
for _, tt := range tests {
if got := solution(tt.input); got != tt.want {
t.Errorf("ReverseInParentheses(%v) = %v, want %v", tt.input, got, tt.want)
}
}
}
Step 2
Iterate string input s
Step 3
- Within the loop, if the current character is
')', the code enters another block. - A variable
iis created and set to the last index of thestackslice. - Reset
tmpvariable
Step 4
- A for loop starts, it runs until
stack[i]is not equal to'(', and decrementing the value ofiin each iteration. - Within the for loop, each character from the
stackslice is appended to thetmpslice. - After the for loop, the
stackslice is updated by replacing the section fromstack[:i]with the reversedtmpslice.
Step 5
- If the current character of the input string
sis not ’)’, it is appended to thestackslice.
Step 6
After the for loop completes, the function returns the stack slice as a string.
Try it yourself https://go.dev/play/p/sDZq7elgytZ
Complexity
time complexity: O(n)
space complexity: O(n)
The time complexity is O(n) because the code iterates through the input string once, and for each character, it takes constant time to append it to the stack slice or reverse the characters within the parentheses. Since the number of characters in the input string is n, the time complexity is O(n).
The space complexity is also O(n) because the code creates two slices, stack and tmp, each with a length of n. As the input string can have at most n characters, the space complexity is also O(n).
Dry Run
Input: foo(bar(baz))blim
- foo(barzab)blim
- foobazrabblim
| iteration | char | stack | tmp |
|---|---|---|---|
| 0 | f | f | |
| 1 | o | fo | |
| 2 | o | foo | |
| 3 | ( | foo( | |
| 4 | b | foo(b | |
| 5 | a | foo(ba | |
| 6 | r | foo(bar | |
| 7 | ( | foo(bar( | |
| 8 | b | foo(bar(b | |
| 9 | a | foo(bar(ba | |
| 10 | z | foo(bar(baz | |
| 11 | ) | foo(barzab | zab |
| 12 | ) | foobazrab | bazrab |
| 13 | b | foobazrabb | bazrab |
| 14 | l | foobazrabbl | bazrab |
| 15 | i | foobazrabbli | bazrab |
| 16 | m | foobazrabblim | bazrab |