2019-拼多多暑期实习笔试-两组括号序列组合后是否合法(python)
题目描述
一个合法的圆括号表达式满足以下条件:
“”空字符串被认为是合法的。
如果字符串“X”与“Y”是合法的,则“XY”也被认为是合法的。
如果字符串“X”是合法的,则“(X)”也是合法的。
例如,“”,“()”,“()()”,“(())”这些都是合法的。
现在给出两个不保证合法的由圆括号组成的字符串,你需要交错这两个圆括号序列(在组成的新字符串中,每个初始字符串都保持原来的顺序)得到一个新的合法的圆括号表达式(不同的交错方式可能得到相同的表达式,这种情况分开计数),求共有多少结果合法的交错方式(无法得到合法的圆括号表达式则输出0),输出结果对109+7取模后的值。
输入格式
输入共两行,每行包含一个由“(”和“)”组成的字符串,长度不超过2500。
输出格式
输出为一个数字,表示合法的交错方式数量对109+7取模后的值。
输入样例:
(()
())
输出样例:
19
思路
属于动态规划的题。
对于括号序列,假设左括号“(”记为1,右括号“)”记为-1,则要使得括号序列合法,在组合括号的过程中累加和cnt始终>=0。
对于输入的一行字符串,建立list记录每个位置的累加和。因为空字符串合法,设置首项为0。比如对于字符串"(()",它对应的list=[0,1,2,1]。
建立初始值为0的二维数组dp存储组合过程中组合方法的值。
对于两组字符串组合,如果二者当下位置的cnt相加>=0,则表明可以进行组合,方法数+1。dp[i][j] = dp[i-1][j],dp[i][j] = dp[i][j-1].
python3实现
import numpy as np
s1 = input()
s2 = input()
mod = 1e9 + 7
n = len(s1)+1
m = len(s2)+1
def ssum(s): #构建ssum函数记录字符串每个对应位置的cnt
cnt = [0]
he = 0
for i in range(len(s)):
if s[i] == '(':
he += 1
else:
he -= 1
cnt.append(he)
return cnt
if n==0 and m==0: # 均为空字符串,则方法数为1
print('1')
elif ssum(s1)[-1]+ssum(s2)[-1] != 0: # 如果两个字符串组合左右括号个数不相等,则无法组合
print('0')
else:
dp = np.zeros((n, m))
dp[0][0] = 1
sum1 = ssum(s1)
sum2 = ssum(s2)
for i in range(n):
for j in range(m):
if sum1[i]+sum2[j] >= 0:
if i :dp[i][j] += dp[i-1][j]
if j: dp[i][j] += dp[i][j-1]
print(int(dp[-1][-1] % mod))