您的位置:首页 > 编程语言 > Go语言

Google APAC test 2015 Round B Problem D-Parentheses Order

2014-09-16 14:31 507 查看
源题地址:
https://code.google.com/codejam/contest/4214486/dashboard#s=p3
题意:

给定数组N和K,找到由N对括号组成的不同的括号组合的中的第K个。

例如,当N=3, K=4时, 返回 "()(())"

因为3对括号组成的括号组合的顺序为:

1、 (((()))

2、 (()())

3、 (())()

4、 ()(())

5、 ()()()

分析:

1、可以用造括号的方法,把所有的n对括号形成的所有合理组合按序全造出来,从中选第K个, 这种方法只能通过小数据

2、直接造第k个组合,要直接造就需要知道pre[l][r], 即l个'('和r个')'形成的合理前缀有多少个, 

也需要知道post[l][r],即l个'('和r个')'形成的合理后缀有多少个。

所谓的合理前缀,就说这个前缀的任何子前缀中 '('数量 >= ')'数量

合理后缀正好相反; 且pre[l][r] = post[r][l],由对称可以得知,所以只需要一个二维表table[][]来记录合理前缀数。

1)生成合理前缀数

table[l][r] = tale[l-1][r] + table[l][r-1]

初始化条件:

table[l][0] = 0 

table[l][r] = 0 (l < r) 

2)生成括号组合(造括号)

#l, r 分别表示已经生成的前缀res中对应的‘(’和‘)’数目

l = 0 

r = 0

res = ""

if k > table[n-r][n-r]:
k大于括号的组合数,所以不存在

while res < 2*N:
if: 写右括号会使得编号超过K and 左括号数量 < n:
写左括号
左括号数+1
elif 写右括号不会使得编号超过K: 
写右括号
变化K值
右括号数+1
else:  #走括号数量 == n
写右括号
右括号数+1

时间负载度:
因为整个过程中最耗时间的是table的生成,每项的生成时间是O(1),所以时间复杂度为O(n^2)

代码:

def getKth(n, k):

table = [ [ 0 for j in range(0, n+1) ] for i in range(0, n+1) ]
table[0][0] = 1

for i in range(1, n+1):
table[i][0] = 1
for j in range(1, i+1):
table[i][j] = table[i-1][j]+table[i][j-1]

res = ""
l = 0
r = 0

if k > table

:
return "Doesn't Exist!"
while len(res) < 2*n:
if k <= table[n-r][n-l-1] and l < n: 
res = res+'('
l = l+1
elif l < n:
res = res+')'
k = k-table[n-r][n-l-1]
r = r+1
else:
res = res+')'
r = r+1

return res

fin = open('d_large.in','r')

fout = open('d_large.out','w')

line = fin.readline()

n = int(line)

for i in range(0,n):

    line = fin.readline()

    line = line.split(' ')

    n = int(line[0])

    k = int(line[1])

    res = getKth(n, k)

    fout.write("Case #%d: %s\n"%(i+1, res))

fin.close()

fout.close()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息