参考:https://blog.csdn.net/zr1076311296/article/details/51723040
題目描述
解题思路
仔细想一想,将字符串逆序后与原来的字符串求最长公共子序列不就是这个构造回文吗?这应该很好理解吧,下面简单科普一下最长公共子序列:这中序列不是连续的,意思是可以有间隔,去掉那些干扰项以后,两个序列完全相同,而且要求这个子序列最长。
这类问题和之前 leetcode 上机器人跳到最右下角那个题一样,是一种动态规划的题。而且这种问题的当前位置的解受前面位置的解的影响,假设 s1,s2为两个字符串,i表示s1中第i个字符,j表示s2中第j个字符,那么:
再一次说明一下解题思路:输入字符串S,将字符串S逆序,逆序后的字符串为tmp,然后求S与tmp的最长公共子序列,最后用S的长度减去最长公共子序列的长度,就是需要删除的元素的个数。 相信思路大家明白思路了,下面给出代码。
AC代码
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int LongestStrHui(string &s)
{
string tmp = s;
//逆序
reverse(tmp.begin(), tmp.end());
int len = s.size();
//初始化二维数组,数组多开辟了一些空间,是为了优化
vector<vector<int>> V(len + 1, vector<int>(len + 1, 0));
//根据"公式"开始去找各个位置的公共子序列长度
for (int i = 0; i < len; ++i)
{
for (int j = 0; j < len; ++j)
{
if (s[i] == tmp[j])
V[i + 1][j + 1] = 1 + V[i][j];
else
V[i + 1][j + 1] = max(V[i][j + 1], V[i + 1][j]);
}
}
//整个序列的最长公共子序列
return len - V[len][len];
}
int main()
{
string s;
while (cin >> s)
{
cout << LongestStrHui(s)<<endl;
}
return 0;
}