我在第一题那里不知道用cin.ignore()去消耗掉换行符,导致getline()也用不了,狠狠的学习了。
第二题其实最主要还是回文串的性质,稍微贪心一下就会发现如果是回文串,那么其内部的长度为2或者为3的也是回文串。越长越容易重合,那么完全可以只去遍历找长度为2或者3的子串,找到一个后就继续往后遍历去找下一个。
第三题说实话,我当时笔试的时候是当地时间的凌晨半夜三点,我也没有在并查集/转换成图下功夫,实在想不到。。。

今天一起床一看发现就已经挂了,非常可惜。。。
第一题送分题,模拟第二题解答题目意思,需要找到字符串的两个子串(长度>2)是回文字符,返回任意两个回文子串的区间即可思路一 动态规划用f[i][j] 表示 [i, j]区间子串是不是回文串状态转移方程:if s[i] == s[j]: f[i][j] = f[i + 1][j - 1]如何递推?普通的dp递推一般是按照方程从前往后递推或者从后往前递推,但是注意到这里的方程里有 i + 1, j - 1 一个往前,一个往后。两个方向都不行,怎么办呢?可以使用队列来递推,比如队列里先保存[i, j],  取出[i, j]后往两边递推,既看[i - 1, j + 1]满不满足回文,是回文的话就放入队列如何初始化?考虑单数和偶数情况单数情况下初始情况为单个字符,单个字符肯定是回文,需要把所有单个字符全部放入队列,既[i, i] (for i in [0, s.length])偶数情况下初始情况为0个字符,肯定是回文,全部放到队列即可,注意区间取值[i, i - 1] (for i in [1, s.length]) 优化题目只需要任意两个回文子串,所以我们找到两个后就可以提前结束思路二 暴力 + 剪枝直接暴力枚举 4个坐标 + 判断回文 是会超时的,可以进行一些优化我们可以剔除一些明显不满足题意的情况,例如我们枚举[i, j, m, n] 四个坐标当[i, j] 区间不为回文时,[m, n]就不需要枚举了对于判断字符串是不是回文,可以用双指针最终伪代码如下for(i in [0, s.length - 3)) for(j in [i + 1, s.length - 2))  if(check(i, j)){ // 检查[i, j]是不是回文   for(m in [j + 1, s.length - 1)){    for(n in [m + 1, s.length)){     if(check(m, n)){      return {i, j, m, n};     }    }   }  }顺带一提,我发现暴力还比第一种思路耗时会小些[喝可乐]第三题n个字符串, 需要两两判断,看两个字符串同一个位置字符差异个数是否小于k,小于k就可以放到同一个集合可以使用并查集,先两层遍历判断两个字符串差异值是否小于k,小于的话就合并最终看并查集里面最大的集合的个数m是不是等于字符串个数n是的话,输出YES不是的话,说明有多个集合,输出NO, 保留最大的集合满足最小操作次数,既 (n - m)最后,如果对你有用的话,求个花花[羞涩]
点赞 3
评论 3
全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务