I spent one day solving this problem and couldn't find a solution to pass the large dataset.
Problem
An n parentheses sequence consists of n "("s and n ")"s.
Now, we have all valid n parentheses sequences. Find the k-th smallest sequence in lexicographical order.
For example, here are all valid 3 parentheses sequences in lexicographical order:
((()))
(()())
(())()
()(())
()()()
Given n and k, write an algorithm to give the k-th smallest sequence in lexicographical order.
For large data set: 1 ≤ n ≤ 100
and 1 ≤ k ≤ 10^18
Let
S= any valid sequence of parentheses from n( and n)
. Now any valid sequence S can be written asS=X+Y
whereX=valid prefix
i.e. if traversing X from left to right , at any point of time,numberof'(' >= numberof')'
Y=valid suffix
i.e. if traversing Y from right to left, at any point of time,numberof'(' <= numberof')'
For any
S
many pairs ofX
andY
are possible.For our example:
()(())
Note that when
X=empty_string
, then number of validS
from n(
and n)
= number of valid suffixY
from n(
and n)
Now, Algorithm goes like this: We will start with
X= empty_string
and recursively growX
untilX=S
. At any point of time we have two options to growX
, either append '(' or append ')'Let
dp[a][b]= number of valid suffixes using a '(' and b ')' given X
nop=num_open_parenthesis_left
ncp=num_closed_parenthesis_left
Lets take example,n=3 i.e. 3
(
and 3)
Now at the very startX=empty_string
, thereforedp[3][3]
= number of valid sequenceS
using 3(
and 3)
= number of valid suffixesY
from 3(
and 3)
This problem can be solved by using dynamic programming
dp[n][m]
= number of valid parentheses that can be created if we haven
open brackets andm
close brackets.dp[0][a] = 1 (a >=0)
dp[n][m] = dp[n - 1][m] + (n < m ? dp[n][m - 1]:0 );
Then, we can slowly build the kth parentheses.
Start with a = n open brackets and b = n close brackets and the current result is empty
Notice that open bracket is less than close bracket in lexicographical order, so we always try to add open bracket first.