Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Give the result string provided minimum number of parenthesis addition done to make string balanced

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.

  • "(){([)}()" -> "(){([])}()"
  • "([)]" -> "([()])" or "()[()]" or "[([])]"

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

like image 905
Shailendra Avatar asked Sep 20 '25 04:09

Shailendra


1 Answers

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.

like image 199
Sayakiss Avatar answered Sep 22 '25 23:09

Sayakiss