我花了一天时间解决this problem并且无法找到传递大型数据集的解决方案。
问题
n括号序列由n"(" s和n")" s组成。
现在,我们拥有所有有效的n个括号序列。找到词典顺序中的第k个最小序列。
例如,以下是按字典顺序排列的所有有效3个括号序列:
((()))
(()())
(())()
()(())
()()()
给定n和k,编写一个算法,以词典顺序给出第k个最小的序列。
对于大型数据集:1 ≤ n ≤ 100
和1 ≤ k ≤ 10^18
答案 0 :(得分:5)
使用动态编程
可以解决此问题dp[n][m]
左括号和n
近括号,则m
=可以创建的有效括号数。dp[0][a] = 1 (a >=0)
dp[n][m] = dp[n - 1][m] + (n < m ? dp[n][m - 1]:0 );
然后,我们可以慢慢建立第k个括号。
以 a = n左括号和 b = n近括号开头,当前结果为空
while(k is not 0):
If number dp[a][b] >= k:
If (dp[a - 1][b] >= k) is true:
* Append an open bracket '(' to the current result
* Decrease a
Else:
//k is the number of previous smaller lexicographical parentheses
* Adjust value of k: `k -= dp[a -1][b]`,
* Append a close bracket ')'
* Decrease b
Else k is invalid
请注意,开放式括号在字典顺序中小于近括号,所以我们总是先尝试添加开括号。
答案 1 :(得分:0)
让S= any valid sequence of parentheses from n( and n)
。
现在任何有效的序列S都可以写成S=X+Y
其中
X=valid prefix
,即如果在任何时间点从左到右遍历X,numberof'(' >= numberof')'
Y=valid suffix
,即如果在任何时间点从右到左遍历Y,numberof'(' <= numberof')'
对于任何S
个X
和Y
都是可能的。
我们的示例:()(())
`()(())` =`empty_string + ()(())`
= `( + )(())`
= `() + (())`
= `()( + ())`
= `()(( + ))`
= `()(() + )`
= `()(()) + empty_string`
请注意,X=empty_string
时,来自n S
和n (
的有效)
的数量=来自n的有效后缀Y
的数量(
和n )
现在,算法是这样的:
我们将从X= empty_string
开始,递归X
增长到X=S
。在任何时候,我们都有两种增长X
的选项,可以追加&#39;(&#39;或追加&#39;)&#39;
让dp[a][b]= number of valid suffixes using a '(' and b ')' given X
nop=num_open_parenthesis_left
ncp=num_closed_parenthesis_left
`calculate(nop,ncp)
{
if dp[nop][ncp] is not known
{
i1=calculate(nop-1,ncp); // Case 1: X= X + "("
i2=((nop<ncp)?calculate(nop,ncp-1):0);
/*Case 2: X=X+ ")" if nop>=ncp, then after exhausting 1 ')' nop>ncp, therefore there can be no valid suffix*/
dp[nop][ncp]=i1+i2;
}
return dp[nop][ncp];
}`
让我们举个例子,n = 3,即3 (
和3 )
现在开始X=empty_string
,因此
dp[3][3]
=使用3 S
和3 (
的有效序列)
的数量
=来自3 Y
和3 (
的有效后缀)
的数量