- 921. Minimum Add to Make Parentheses Valid 使括号有效的最少添加
- 915. Partition Array into Disjoint Intervals 分割数组
- 932. Beautiful Array 漂亮数组
- 940. Distinct Subsequences II 不同的子序列 II
题目地址:https://leetcode.com/problems/longest-palindromic-subsequence/description/
Given a string s, find the longest palindromic subsequence's length in s. You may assume that the maximum length of s is 1000.
Example 1:
Input:
"bbbab"
Output:
4
One possible longest palindromic subsequence is "bbbb".
Example 2:
Input:
"cbbd"
Output:
2
One possible longest palindromic subsequence is "bb".
找出一个字符串中最长的回文序列的长度。注意序列可以是不连续的,而子字符串是连续的。
做完昨天的每日一题 446. 等差数列划分 II - 子序列open in new window 之后,相信大家对于子序列问题的套路已经更加了解了。子序列问题不能用滑动窗口了,可以用动态规划来解决。子序列问题的经典题目就是 300. 最长递增子序列open in new window,务必掌握。
先从整体思路说起。
子序列问题,由于是数组中的非连续的一个序列,使用动态规划求解时,避免不了二重循环:第一重循环是求解动态规划的每一个状态 dp[i],(0<=i<=N) ,第二重循环是向前寻找上一个子序列的结尾 j,(0<=j<i)$ 来和 i 一起构成满足题意的新的子序列。
在动态规划问题中,我们找到一个符合条件的 j ,然后就可以通过状态转移方程由 dp[j] 推导出 dp[i] 。
然后,我理一下本题的解法。
当已知一个序列是回文时,在其首尾添加元素后的序列存在两种情况:
1、 首尾元素相等,则最长回文的长度+2;
2、 首尾元素不相等,则最长回文序列长度为仅添加首元素时的最长回文长度与仅添加尾元素时的最长回文长度的最大值;
状态定义: dp[i][j] 表示 s[i…j] 中的最长回文序列长度。
状态转移方程:
1、 i>j,dp[i][j]=0;
2、 i==j,dp[i][j]=1;
3、 i<j且s[i]==s[j],dp[i][j]=dp[i+1][j−1]+2;
4、 i<j且s[i]!=s[j],dp[i][j]=max(dp[i+1][j],dp[i][j−1]);
遍历顺序: 从状态转移方程可以看出,计算 dp[i][j] 时需要用到 dp[i+1][j−1] 和 dp[i+1][j],所以对于 i 的遍历应该从后向前;对于 j 的遍历应该从前向后。
返回结果: 最后返回 dp[0][s.length()−1]。
提供了三种语言的代码。
java 代码
class Solution {
public int longestPalindromeSubseq(String s) {
int size = s.length();
int[][] dp = new int[size][size];
for(int i = size - 1; i >= 0; i--){
dp[i][i] = 1;
for(int j = i + 1; j < size; j++){
if(s.charAt(i) == s.charAt(j)){
dp[i][j] = dp[i + 1][j - 1] + 2;
}else{
dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]);
}
}
}
return dp[0][size - 1];
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
C++代码:
class Solution {
public:
int longestPalindromeSubseq(string s) {
int size = s.size();
vector<vector<int>> dp(size, vector<int>(size, 0));
for(int i = size - 1; i >= 0; i--){
dp[i][i] = 1;
for(int j = i + 1; j < size; j++){
if(s[i] == s[j]){
dp[i][j] = dp[i + 1][j - 1] + 2;
}else{
dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
}
}
}
return dp[0][size - 1];
}
};
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
python 代码:
class Solution:
def longestPalindromeSubseq(self, s):
n = len(s)
dp = [[0] * n for _ in range(n)]
for i in range(n - 1, -1, -1):
dp[i][i] = 1
for j in range(i + 1, n):
if s[i] == s[j]:
dp[i][j] = dp[i + 1][j - 1] + 2
else:
dp[i][j] = max(dp[i + 1][j], dp[i][j - 1])
return dp[0][n - 1]
1 2 3 4 5 6 7 8 9 10 11 12
子序列的动态规划解法:两重循环。其实就看对于每个 i,当找到满足题目要求的 j 的时候,状态转移方程怎么变化。
参考:http://blog.csdn.net/camellhf/article/details/70337501
DDKK.COM 弟弟快看-教程,程序员编程资料站,版权归原作者所有
本文经作者:负雪明烛 授权发布,任何组织或个人未经作者授权不得转发
dic = {'a':4, 'b':5, 'cd':5 } 我正在寻找: 最高值(首先搜索最高值 => b, cd) 最长的键(然后搜索最长的键 => 'cd') 我使用以下代码: max_val =
dic = {'a':4, 'b':5, 'cd':5 } 我正在寻找: 最高值(首先搜索最高值 => b, cd) 最长的键(然后搜索最长的键 => 'cd') 我使用以下代码: max_val =
题目地址:https://leetcode.com/problems/longest-palindrome/open in new window Difficulty: Easy 题目描
题目地址:https://leetcode-cn.com/problems/longest-happy-string/ 题目描述 如果字符串中不含有任何 'aaa','bbb' 或 'ccc' 这
本文关键词:prefix, 公共前缀,题解,leetcode, 力扣,Python, C++, Java 题目地址:https://leetcode.com/problems/longest-com
最长回文子串,题解,leetcode, 力扣,python, C++, java 题目地址:https://leetcode.com/problems/longest-palindromic-sub
题目地址:https://leetcode.com/problems/longest-increasing-subsequence/description/ 题目描述 Given an unsor
题目地址:https://leetcode.com/problems/longest-palindromic-subsequence/description/ 题目描述 Given a strin
题目地址:https://leetcode.com/problems/longest-word-in-dictionary/description/open in new window 题目描述
题目地址:https://leetcode.com/problems/longest-mountain-in-array/description/ 题目描述 Let's call any (con
路由器 (IPv4) Destination Interface 0.0.0.0/0 m0 172.58.128.0/17 m1 1
我想找到给定目录中子目录中最长的路径,因为我遇到了这个错误: The specified path, file name, or both are too long. The fully qualif
我正在尝试创建一个Java程序,该程序读取键盘输入的数字字符串, 并给出最长的升序子字符串。 以下是我的代码: import java.util.Scanner; public class Ascen
我正在尝试编写一个正则表达式来识别单行文本,下划线 ( _ ) 被识别为行继续符。例如,“foo_\nbar”应被视为单行,因为“foo”以下划线结尾。我在尝试: $txt = "foo_\nbar"
我可能在这里做了一些非常愚蠢的事情,但我已经达到了 double 可以达到的极限,并且在我的编译器上(我在 mac 上使用最新的 xcode)long double 似乎也好不到哪里去。 我在别处读到
我已经阅读了 LCS 问题的解决方案。但是现在有一个最长相似子序列问题:序列 C 是两个序列 A、B 的相似子序列当且仅当 C 是 A 的子序列并且我们最多可以替换 C 中的 K 个元素使得 C 是
我将复习在寻找两个等长字符串的最长公共(public)子序列的上下文中讨论动态规划的笔记。有问题的算法输出长度(不是子字符串)。 所以我有两个字符串,比如说: S = ABAZDC,T = BACBA
题目是解决 Sedgewick Wayne 的 Python 书中的以下问题: 给定一个整数数组,编写一个程序,找出最长的连续等值序列的长度和位置,其中该序列前后元素的值较小。 我试过这个问题,遇到了
我们可以用DP(动态规划)找到两个字符串的LCS(最长公共(public)子序列)。通过跟踪 DP 表,我们可以获得 LCS。但是,如果存在不止一个濒海战斗舰,我们如何获得所有的濒海战斗舰呢? 例子:
过去两个小时我一直试图理解这个算法,但似乎无法理解。有人可以用通俗易懂的方式解释一下吗? function lis_length(a) n := a.length q := new A
我是一名优秀的程序员,十分优秀!