1771. Maximize Palindrome Length From Subsequences
题意及示例输入如下:
You are given two strings, word1 and word2. You want to construct a string in the following manner:
Choose some non-empty subsequence subsequence1 from word1.
Choose some non-empty subsequence subsequence2 from word2.
Concatenate the subsequences: subsequence1 + subsequence2, to make the string.
Return the length of the longest palindrome that can be constructed in the described manner. If no palindromes can be constructed, return 0.
A subsequence of a string s is a string that can be made by deleting some (possibly none) characters from s without changing the order of the remaining characters.
A palindrome is a string that reads the same forward as well as backward.
Example 1:
Input: word1 = "cacb", word2 = "cbba"
Output: 5
Explanation: Choose "ab" from word1 and "cba" from word2 to make "abcba", which is a palindrome.
Example 2:
Input: word1 = "ab", word2 = "ab"
Output: 3
Explanation: Choose "ab" from word1 and "a" from word2 to make "aba", which is a palindrome.
Example 3:
Input: word1 = "aa", word2 = "bb"
Output: 0
Explanation: You cannot construct a palindrome from the described method, so return 0.
分析:
这道题刚拿到手感觉没什么头绪,对于单字符串,我们直接按照求回文子串最大长度的方法做就行,思路就是一个二维DP, dp[i][j]数组的含义就是从i位置到j位置的回文子串最大长度。我们知道任何一个字符都是一个回文子串,所以所有的dp[i][i]都是1
按照让子字符串长度L逐渐增加,给定i,j是i+L-1,我们判断i位置的字符和j位置的字符是否相等,如果相等,那么dp[i][j]就等于去掉i字符,去掉j字符,之前的字符串的最大回文子串长度dp[i+1][j-1]的长度+2,否则就选择dp[i+1][j]和dp[i][j-1]之间的最大值。
那么回到这个问题,我们可以看到这里给了两个字符串 word1 word2,我们又知道这里新字符串word是以word1+word2的顺序来的,且每一个word里出的字符串非空,这就意味着每一个字符串都要对最终的回文子串有贡献。那么我们可以考虑还用上面的方法,但是在更新dp的时候,只有当j处于word2范围内的时候,我们才更新最终的结果,所以本题最终可以拆解为单串的最大回文子串+多串合并+j的位置特判更新。虽然这是一道hard题,但是似乎也并没有特别难,感觉遇到这种问题,先写出自己会的,再尝试修改,比闷着头想要好很多。
下面上代码:
class Solution:
def longestPalindrome(self, word1: str, word2: str) -> int:
if len(word1)==1 and len(word2)==1:
if word1==word2:
return 2
else:
return 0
word = word1+word2
dp = [[0]*len(word) for _ in range(len(word))]
res = 2 if word[len(word1)-1]==word[len(word1)] else 0
for i in range(len(word)):
dp[i][i]=1
for i in range(len(word)-1):
dp[i][i+1] = 2 if word[i]==word[i+1] else 1
for l in range(2,len(word)):
for i in range(0,len(word)-l):
j = i+l
if word[i]==word[j]:
dp[i][j] = dp[i+1][j-1]+2
if i<len(word1) and j>=len(word1):
res = max(res,dp[i][j])
else:
dp[i][j] = max(dp[i][j-1],dp[i+1][j])
return res
2021. 8.9 LC每日进步群挑战 兴趣使然