今天有點累,不如來個刷個題吧,記得參加騰訊在線筆試的時候遇到過一道題,確實比較懵,所以今天就好好的想了想,這個題來自牛客網...
看到這個圖的時候相信大家明白了吧,就是這個題,我一直沒有思路,今天突然想起來了,所以就準備解決它。其實這個題主要是運用一個算法思路來解決,最長公共子序列。
仔細想一想,將字符串逆序後與原來的字符串求最長公共子序列不就是這個構造迴文嗎?這應該很好理解吧,下面簡單科普一下最長公共子序列:這中序列不是連續的,意思是可以有間隔,去掉那些干擾項以後,兩個序列完全相同,而且要求這個子序列最長。
這類問題和之前 leetcode 上機器人跳到最右下角那個題一樣,是一種動態規劃的題。而且這種問題的當前位置的解受前面位置的解的影響,假設 s1,s2爲兩個字符串,i表示s1中第i個字符,j表示s2中第j個字符,那麼:
再一次說明一下解題思路:輸入字符串S,將字符串S逆序,逆序後的字符串爲tmp,然後求S與tmp的最長公共子序列,最後用S的長度減去最長公共子序列的長度,就是需要刪除的元素的個數。 相信思路大家明白思路了,下面給出代碼。
#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;
}