1. 程式人生 > >騰訊2016實習筆試題(最長迴文子序列)

騰訊2016實習筆試題(最長迴文子序列)

問題描述

迴文串:首位相同的字串,如:abba   aca

迴文序列:在字串裡面刪除一個或多個字元,剩餘的字元組成迴文串。如:abbceda    刪除"ced",剩餘abba組成迴文序列

最長迴文子序列:一個字串裡面所有迴文序列裡面,最長的序列。

//問題求解

//判斷迴文字串很簡單,直接同時首尾遍歷字串,只要找到不相同的則不是迴文字串
//容易想到的暴力解決辦法,先得到字串的所有子序列,然後判斷序列是否是迴文串,並記錄長度
//從而得到最長的迴文序列,但這種方式肯定是不可取的,
//假如原始字串長度為n,則其所有子序列個數為2^n,時間複雜度太高
//其實這個問題跟最長公共子序列問題類似,因此解決辦法也可以借鑑LCS求解。
//令LPS(m, n)表示下標為m-1到n-1的字串的最長迴文子序列長度,
//現在要求解LPS(m, n+1)的最長迴文子序列長度,如果下標m-1與n處相等,則LPS(m, n+1) = LPS(m+1, n)+2
//否則LPS(m, n+1)就等於LPS(m+1, n)與LPS(m, n+1)的較大值。(思路與LCS基本一致)

//因此可以設計遞迴實現

#include <iostream>
#include <string>

using namespace std;

int LPS_RECU(string str, int m, int n)     //表示求m到n的最長迴文子序列長度
{
	
	if (m == n)
		return 1;
	if (m > n)
		return 0;

	if (str[m-1] == str[n - 1])
		return LPS_RECU(str, m+1, n - 1) + 2;
	else
	{
		int l1 = LPS_RECU(str, m, n - 1);
		int l2 = LPS_RECU(str, m+1, n);

		return l1 > l2 ? l1 : l2;
	}
		
}



int _tmain(int argc, _TCHAR* argv[])
{

	string str;
	cin >> str;

	cout << LPS_RECU(str, 1, str.length()) << endl;

	return 0;
}