网易编程题 最长公共子括号序列 Python

14 篇文章 0 订阅
13 篇文章 0 订阅

最长公共子括号序列 (Python)

一个合法的括号匹配序列被定义为:
1. 空串”“是合法的括号序列
2. 如果”X”和”Y”是合法的序列,那么”XY”也是一个合法的括号序列
3. 如果”X”是一个合法的序列,那么”(X)”也是一个合法的括号序列
4. 每个合法的括号序列都可以由上面的规则生成
例如”“, “()”, “()()()”, “(()())”, “(((()))”都是合法的。
从一个字符串S中移除零个或者多个字符得到的序列称为S的子序列。
例如”abcde”的子序列有”abe”,”“,”abcde”等。
定义LCS(S,T)为字符串S和字符串T最长公共子序列的长度,即一个最长的序列W既是S的子序列也是T的子序列的长度。
小易给出一个合法的括号匹配序列s,小易希望你能找出具有以下特征的括号序列t:
1、t跟s不同,但是长度相同
2、t也是一个合法的括号匹配序列
3、LCS(s, t)是满足上述两个条件的t中最大的
因为这样的t可能存在多个,小易需要你计算出满足条件的t有多少个。

如样例所示: s = “(())()”,跟字符串s长度相同的合法括号匹配序列有:
“()(())”, “((()))”, “()()()”, “(()())”,其中LCS( “(())()”, “()(())” )为4,其他三个都为5,所以输出3.

输入描述:

输入包括字符串s(4 ≤ |s| ≤ 50,|s|表示字符串长度),保证s是一个合法的括号匹配序列。

输出描述:

输出一个正整数,满足条件的t的个数。

示例1
输入

(())()

输出

3

代码:

## 输入转为字符串
s = list(input())
## 保存 t 序列
s_set = []
length = len(s)
# 遍历序列中每个值,采用pop删除,接着用insert插入在不同位置
# 当序列合法时保存 
# 合法性判断依据 无论序列多长,序列从左到右,num('(')>=num(')')始终成立
# 初始化计数器count ,当count==lenght, 数据合法,进行保存
# 即每次计数中num('(')>=num(')')成立,计数器+1,
# 最后len(t)即可
for i in range(length):
    s_1 = s.copy() #初始化序列
    value = s_1.pop(i) #
    s_new = s_1.copy()
    for j in range(length):
        s_new.insert(j,value)
        ###判断合法性
        num_left = num_right = 0
        count = 0
        for p in range(length):
            num_left = len([x for x in s_new[:p] if x == '('])
            num_right = len([x for x in s_new[:p] if x == ')'])
            if num_left >= num_right:
                count += 1
        ## 如果在每次循环中num('(')>=num(')')始终成立,则会有count=length
        if count == length:
            if s_new not in s_set:
                s_set.append(s_new)
        s_new = s_1.copy()

s_result = [s]
for i in s_set:
    if i not in s_result:
        s_result.append(i)
print (len(s_result)-1)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值