题解 | #最长回文子序列#

最长回文子序列

https://www.nowcoder.com/practice/82297b13eebe4a0981dbfa53dfb181fa

直接套用这个递归的方法会部分用例超时。
参考评论区的题解可以高效解决:
  //dp[i][j]指字符串s在[i, j]范围内最长的回文子序列的长度。
  //在判断回文子串的题目中,关键逻辑就是看s[i]与s[j]是否相同。
  //如果s[i]与s[j]相同,那么dp[i][j] = dp[i + 1][j - 1] + 2;
  //如果s[i]与s[j]不相同,说明s[i]和s[j]的同时加入 并不能增加[i,j]区间回文子串的长度,那么分别加入s[i]、s[j]   看看哪一个可以组成最长的回文子序列。
  //加入s[j]的回文子序列长度为dp[i + 1][j]。
  //加入s[i]的回文子序列长度为dp[i][j - 1]
  //那么dp[i][j]一定是取最大的,即:dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s;
    cin >> s;
    vector<vector<int> >dp(s.size(),vector<int>(s.size(),0));
  //dp[i][j]指字符串s在[i, j]范围内最长的回文子序列的长度。
  //在判断回文子串的题目中,关键逻辑就是看s[i]与s[j]是否相同。
  //如果s[i]与s[j]相同,那么dp[i][j] = dp[i + 1][j - 1] + 2;
  //如果s[i]与s[j]不相同,说明s[i]和s[j]的同时加入 并不能增加[i,j]区间回文子串的长度,那么分别加入s[i]、s[j]   看看哪一个可以组成最长的回文子序列。
  //加入s[j]的回文子序列长度为dp[i + 1][j]。
  //加入s[i]的回文子序列长度为dp[i][j - 1]
  //那么dp[i][j]一定是取最大的,即:dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
    for(int i = 0;i<s.size();i++)dp[i][i] = 1;
    for(int i = s.size()-1;i >= 0;i-- )
    {
        for(int j = i+1;j < s.size();j++)
        {
            if(s[i] == s[j])dp[i][j] = dp[i+1][j-1] + 2;
            else dp[i][j] = max(dp[i][j-1],dp[i+1][j]);
        }
    }
    cout<<dp[0][s.size()-1];
    return 0;
}


全部评论
因为dp[i][j]的值与max(dp[i][j-1],dp[i+1][j]);有关,i+1, j-1 故遍历时先要算出i比较大的值,j比较小的值,所以i是从后往前遍历,j是从i+1处递增遍历。
点赞 回复 分享
发布于 2022-10-13 21:39 陕西

相关推荐

不愿透露姓名的神秘牛友
昨天 13:47
点赞 评论 收藏
分享
点赞 评论 收藏
分享
湫湫湫不会java:1.在校经历全删了2.。这些荣誉其实也没啥用只能说,要的是好的开发者不是好好学生3.项目五六点就行了,一个亮点一俩行,xxx技术解决,xxx问题带来xxx提升。第一页学历不行,然后啥有价值的信息也没有,到第二页看到项目了,第一个项目九点,第二个项目像凑数的俩点。总体给人又臭又长,一起加油吧兄弟
点赞 评论 收藏
分享
05-29 20:34
门头沟学院 C++
KarlAllen:得做好直接春招的准备。学历差的话,一是面试要求会比学历好的严格不少,二是就算面试通过了也会被排序。总之暑期和秋招对于学历差的就是及其不友好
无实习如何秋招上岸
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务