leetcode 每日进步群本周打卡-2

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每日进步群挑战 兴趣使然

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值