Brute Force way: Stack
class Solution:
def minInsertions(self, s: str) -> int:
""" tc O(N) sc O(N)
main idea: 1. each time encountered (, push into st; each time encountered ), chech st[-1] is empty, ( or )
if empty, need to insert (
if ( means we have first ), push into st
if ), pop() twice
2. decluter st, if st[-1] is (, pop() and cnt +2
if st[-1] is ) cnt -= 1
"""
st, cnt = [],0
for c in s:
if c == '(':
if st and st[-1]==')':
# st.append(')')
# st.pop()
st.pop()
st.pop()
cnt += 1
st.append(c)
else:
if not st:
st.append('(') #here we guaranteen in stack there is only () there is not )( ==> when st[-1], len(st) is at least 2
cnt += 1
st.append(c)
elif st and st[-1] == '(':
st.append(c)
elif st and st[-1] == ')':
st.pop()
st.pop()
while st:
if st[-1] == '(':
st.pop()
cnt += 2
else:
if len(st) > 1:
st.pop()
st.pop()
cnt += 1
else:
st.pop()
cnt += 2
return cnt
One Round with counting
class Solution:
def minInsertions(self, s: str) -> int:
""" tc O(N) sc O(1)
main idea: keep track of # close paratheses ) and # of parathesis is inserted; answer = ins + closes
two cases (1) c == (
(2) c == )
"""
ins = closes = 0
for c in s:
if c == '(':
if closes % 2 : # imply there is an extra )
ins += 1
closes -= 1 #means after new ( is inserted, there extra ) is consumed
closes += 2
else: # c == )
closes -= 1
if closes < 0 : # there is extra ) so far, we need to insert ( to pair it
ins += 1
closes += 2
return closes + ins