1771.由子序列构造的最长回文串的长度
📎 1771.由子序列构造的最长回文串的长度
给你两个字符串 word1
和 word2
,请你按下述方法构造一个字符串:
- 从
word1
中选出某个 非空 子序列subsequence1
。 - 从
word2
中选出某个 非空 子序列subsequence2
。 - 连接两个子序列
subsequence1 + subsequence2
,得到字符串。
返回可按上述方法构造的最长 回文串 的 长度 。如果无法构造回文串,返回 0
。
字符串 s
的一个 子序列 是通过从 s
中删除一些(也可能不删除)字符而不更改其余字符的顺序生成的字符串。
回文串 是正着读和反着读结果一致的字符串。
思路
基本思想
本题看完之后第一思想是将两个字符串拼接在一起形成一个字符串,这样就可以利用
516.最长回文子序列
的解法直接进行求解,但是按照这种方式求解之后,发现只能解决一部分问题,例如word1=”bcb“,word2="a"
时,最终求出来的结果是”bcb“
而返回3,而不是返回0,因为word2
中没有提供任何字符串。并且如果出现word1 = "aa", word2 = "bb"
时,会返回1并不会返回0,这是因为
516.最长回文子序列
的解法认为一个字符也是一个回文串,但是本题中不会
知道这两个题的差异之后,我们就要想办法在 516.最长回文子序列 的解法基础上剔除这些不符合条件的回文串,然后在剩下的回文串中找到一个最长的回文子序列,先给出 516.最长回文子序列 的解法的代码:
|
|
根据上面的代码进行分析,主要的问题出现在更新res和res的初值上,在更新的过程中,i和j分别代表当前这个子序列的左边界和右边界,所以只有当左边界在word1
中,右边界在word2
中时才能更新res,并且res的初值不能是1而是0,因为题目要求word1
和word2
中都必须选择至少一个字符,所以res要么是大于1的数,要么就是0,不可能是1
核心就是在 516.最长回文子序列 的解法基础上进一步增加筛选条件进行筛选
执行流程
- 将
word1
和word2
合并并转换成字符数组 - 初始化一个二维
dp
数组,其中dp[i][j]
代表范围i~j之间的最长回文子序列的长度 - 按照 516.最长回文子序列 的解法更新dp数组
- 改变res的初始和更新方式,只有当回文串的左边界在
word1
中,右边界在word2
中时才更新 - 更新完毕之后返回结果
代码
根据以上分析,得出以下代码:
|
|
总结
主要是要有
516.最长回文子序列
的基础,然后看到这个题想到
516.最长回文子序列
的解法之后,出现一些问题,主要是一些不合法的回文串被统计了,而且res
的初值设置的不对,解决这两个问题之后,问题迎刃而解,相当于在
516.最长回文子序列
的解法上进行了进一步的筛选,只有左边界在word1
中右边界在word2
中的回文串才需要被统计