首页 > 试题广场 >

最长公共子括号序列

[编程题]最长公共子括号序列
  • 热度指数:133 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 98M,其他语言196M
  • 算法知识视频讲解
一个合法的括号匹配序列被定义为:
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
//思路2:通过分析可知,当修改距离为1的时候LCS长度最长,比如java,当删除任意一个字符比如j,
再将它放在放到任意为如avaj,那么LCS就是ava, //只移动一个字符肯定是可以让LCS长度最长的。接下来就只需要遍历每个字符放到任意位置,再判断合法性并通过set去重来累计。 //至于判断合法性,只需要遍历这个字符串,“(”和“)”因该是配对的,即个数都为1/2的字符串长度,
但是遍历过程中保持左括号暂时多于右括号 //但不可以少于,因为左括号可以暂时先出现,之后再由右括号填起来。

import java.util.*;
public class Main{
        public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        String str = in.next();
        Set<String> set = getSequence(str);
        System.out.println(set.size()-1);
    }

    private static Set<String> getSequence(String str) {
        Set<String> set = new HashSet<>();
        for(int i=0;i<str.length();i++){
            StringBuilder sb  = new StringBuilder(str);
            char c = str.charAt(i);
            sb.deleteCharAt(i);
            for(int j=0;j<str.length();j++){
                sb.insert(j,c);
                if(isLegal(sb.toString())){
                    set.add(sb.toString());
                }
                sb.deleteCharAt(j);
            }
        }
        return set;
    }

    private static boolean isLegal(String s) {
        int count = 0;
        for(int i=0;i<s.length();i++){
            if(s.charAt(i)=='('){
                count++;
            }else {
                count--;
            }
            if(count<0)
                return false;
        }
        return true;
    }
}
发表于 2018-06-07 15:11:55 回复(0)
s=raw_input()
def islegal(ss):
    count=0
    for i in ss:
        if i=='(':
            count+=1
        else:
            count-=1
        if count<0:
            return False
    return True
res,n=[],len(s)
for i in range(n):
    temp1=s[:i]+s[i+1:]
    for j in range(n-1):
        temp2=temp1[:j]+s[i]+temp1[j:]
        if islegal(temp2):
            if temp2 not in res:
                res.append(temp2)
print(len(res)-1)

发表于 2018-07-30 16:28:11 回复(0)