A good follow up question asked in one of the interview post 'valid parentheses' problem.
Given an imbalanced parentheses string, return the result string(any one of multiple solutions) with balanced parentheses provided minimum number of parentheses addition is done.
Eg.
It is easy to get the count of minimum addition needed for balanced string but exact string was tricky and could not come to optimal solution taking minimum addition for getting the string.
I was leaning towards use of recursive/dynamic programming solution evaluating every choice of minimum length balanced substring formed.
Any suggestions/approach would be welcome
We define text
as input parentheses string and:
sol(x, y) = min_addition_count to handle text[x:y]
And sol(x, y) is the minimum of these two cases:
1. sol(x + 1, y - 1) if text[x] and text[y] is match(eg. text[x] is '(' and text[y] is ')')
2. sol(x, i) + sol(i + 1, y) for i >= x and i < y
For the corner cases, we have:
sol(x, y) = 1 for x == y
sol(x, y) = 0 for x > y
During the solving, we record where our solution(the minimum addition account) comes from, and then we can find the solution after we get it.
You can check my Python code for details:
def find_solution(text):
mem = {}
# mem[x, y] is a tuple (α, β), where α is the minimum addition count, and β is where α comes from.
# so β can be 2 cases: [(x + 1, y - 1)] or [(x, x + i), (i + 1, y)]
def sol(x, y):
if mem.get((x, y)) is not None:
return mem[x, y]
if x > y:
mem[x, y] = 0, None
return mem[x, y]
if x == y:
mem[x, y] = 1, None
return mem[x, y]
ans = len(text), []
if (text[x] == '(' and text[y] == ')') or (text[x] == '[' and text[y] == ']') or (
text[x] == '{' and text[y] == '}'):
if ans[0] >= sol(x + 1, y - 1)[0]: # case1
ans = sol(x + 1, y - 1)[0], [(x + 1, y - 1)]
mem[x, y] = ans
for i in range(x, y):
if ans[0] >= sol(x, i)[0] + sol(i + 1, y)[0]: # case2
ans = sol(x, i)[0] + sol(i + 1, y)[0], [(x, i), (i + 1, y)]
mem[x, y] = ans
return mem[x, y]
def get_solution(x, y):
if x > y:
return ''
if x == y:
t = text[x]
if t == '(' or t == ')':
return '()'
if t == '[' or t == ']':
return '[]'
if t == '{' or t == '}':
return '{}'
sol = mem[x, y]
if len(sol[1]) == 1:
return text[x] + get_solution(*sol[1][0]) + text[y]
if len(sol[1]) == 2:
return get_solution(*sol[1][0]) + get_solution(*sol[1][1])
sol(0, len(text) - 1)
return get_solution(0, len(text) - 1)
print(find_solution('(){([)}()'))
print(find_solution(')))'))
print(find_solution('([)]'))
print(find_solution('()()'))
print(find_solution('()[()}'))
print(find_solution('({)[]'))
Output:
(){([])}()
()()()
([])[]
()()
()[](){}
({})[]
If you have any questions, please do not hesitate to comment here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With