腾讯2017暑期实习生编程题--删除最少的元素,获得最长回文串

it2025-04-22  10

题目

这道应该是三道题中最难的,因为之前在leetcode上做过最长回文字串,典型的动态规划 回文问题动态规划的关键在于,只要中间部分是回文,并且两边相等,那么也会构成回文,这样就可以基于前一状态获得当前状态了! 难点在于写出构造方程(废话。。),在于当左右指针不等的时候如何推出结果!

#include<string> #include<iostream> #include<vector> using namespace std; int Solution(string s){ int length = s.size(); vector<vector<int>> dp(length,vector<int>(length,0)); for(int l=0;l<length;l++){ for(int i=0;i+l<length;i++){ int j = i+l; if(l<=1){ if(s[i] != s[j]) dp[i][j] = 1; } else{ if(s[i]!=s[j]){ //难点所在!! dp[i][j] = min(dp[i][j-1],dp[i+1][j]) + 1; } else dp[i][j] = dp[i+1][j-1]; } } } return dp[0][length-1]; } int main(){ string s; while(cin>>s){ cout<<Solution(s)<<endl; } return 0; }

看其他人的`题解还有一种方法是,将字符串逆序,然后计算两者的“最大公共子序列”,注意了,子序列是不需要连续的,而子串是需要连续的! 单独把“最大公共子序列”列出来: 这题的dp构造比较奇特,我用dp[i][j]表示:对于string1,从0~i,和对于string2,从0~j,两部分之间的最大公共子序列的长度! 那么,得出状态转移方程:

当str1[i] == str2[j]的时候,dp[i][j] = dp[i-1][j-1] + 1; 当str1[i] != str2[j]的时候,dp[i][j] = max(dp[i][j-1],dp[i-1][j]),这是题目的关键 class Solution { public: int longestCommonSubsequence(string text1, string text2) { int length1 = text1.size(); int length2 = text2.size(); vector<vector<int>> dp(length1,vector<int>(length2,0)); if(text1[0] == text2[0]) dp[0][0] = 1; for(int i=1;i<length1;i++){ if(text2[0] == text1[i]) dp[i][0] = 1; else dp[i][0] = dp[i-1][0]; } for(int j=1;j<length2;j++){ if(text1[0] == text2[j]) dp[0][j] = 1; else dp[0][j] = dp[0][j-1]; } for(int i=1;i<length1;i++){ for(int j=1;j<length2;j++){ if(text1[i]!=text2[j]) //这题的重点!! dp[i][j] = max(dp[i][j-1],dp[i-1][j]); else dp[i][j] = dp[i-1][j-1] + 1; } } return dp[length1-1][length2-1]; } };
最新回复(0)