网易2017秋招笔试题3:最长公共子括号序列长度

Posted hedgehog小子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网易2017秋招笔试题3:最长公共子括号序列长度相关的知识,希望对你有一定的参考价值。

【问题来源】网传的2017网易秋招笔试题

【问题描述】

 

【算法思路】

 下面的解题思路摘自  http://www.cnblogs.com/Atanisi/p/7500186.html

刚看到题我就想到暴力解,深搜出所有合法的括号序列,再依次比较公共子序列的长度,返回最长的。但是深搜一般和路径有关,这道题仅仅需要最大公共子序列的长度。而我们发现最大公共子序列的长度就是 s.size() - 1(当且仅当修改距离为 1 时 LCS 最大), 那么我们就想到,可以变换 s 中一个括号的位置,枚举所有的最大公共子序列长度的序列,只是需要判断是否合法。注意到,深搜是枚举所有合法的相同长度的序列,然后我们再在这个集合中去最长的。而后一种思路是我们枚举所有最长公共子序列的序列,然后再在这个集合中去掉非法的和重复的。

因为是 s, t 长度相同,并且 t 也是合法的括号序列,所以正反括号数跟原来一样。考虑在原序列上枚举一个字符,把这个插入依次到序列的某个位置去,其他序列相对顺序不变,,这样就可以让LCS最大,然后我们判断一下是否合法(这里有个小技巧),去重就用 set。

 

【代码】

 1 #include <iostream>
 2 #include <string>
 3 using namespace std;
 4 
 5 int main() {
 6     string s;
 7     cin >> s;
 8     set<string> m;
 9     int n = s.size();
10     for (int i = 0; i < n; ++i) {
11         string w = s.substr(0, i) + s.substr(i + 1);
12         for (int j = 0; j < n - 1; ++j) {
13             string tmp = w.substr(0, j) + s[i] + w.substr(j);
14             int num = 0;
15             for (int k = 0; k < n; ++k) {
16                 num += (tmp[k] == \'(\' ? 1 : -1);
17                 if (num < 0)
18                     break;
19             }
20             if (num >= 0)
21                 m.insert(tmp);
22         }
23     }
24     cout << (int)m.size() - 1 << endl;
25 
26     return 0;
27 }

 

以上是关于网易2017秋招笔试题3:最长公共子括号序列长度的主要内容,如果未能解决你的问题,请参考以下文章

笔试题学习(dp,重叠子问题,卡特兰数,手电过桥,最长公共子序列)

TX2017秋招笔试题之素数对

贼有意思[最长上升公共子序列](SAC大佬测试题)

阿里巴巴2021秋招笔试题20211119

最长公共子序列的长度

阿里巴巴2021秋招笔试题20211119