Longest Palindromic Subsequence 最长回文子序列

给定一个字符串s,找到其中最长的回文子序列。可以假设s的最大长度为1000

示例 1:
输入:

"bbbab"

输出:

4

一个可能的最长回文子序列为 "bbbb"。

示例 2:
输入:

"cbbd"

输出:

2

一个可能的最长回文子序列为 "bb"。

思路一,动态规划维护一个二维数组dp,其中dp[i][j]表示第i个下标到第j个下标的最长回文子序列的数量。那么dp[i][j]的递推公式如下:

dp[i][j]=dp[i+1][j-1]+2            if s[i]==[j]
        =max(dp[i+1][j],dp[i][j-1])     if s[i]!=s[j]

递推公式的意义是如果s[i]==s[j],那么首尾字符相等,从i~j的最大回文子序列等于其内字符串[i+1,j-1]+2。如果不相等,俺么最大回文子字符串在[i+1,j]和[i,j-1]中选择一个最大的。

参考代码:

扫描二维码关注公众号,回复: 1855468 查看本文章
class Solution {
public:
    int longestPalindromeSubseq(string s) {
	if (s.size() <= 1) {
		return s.size();
	}
	vector<vector<int>> dp(s.size(), vector<int>(s.size(), 0));
	int n = s.size();
	for (int i = n - 1; i >= 0; i--) {
		dp[i][i] = 1;
		for (int j = i + 1; j < n; j++) {
			if (s[i] == s[j]) {
				dp[i][j] = dp[i + 1][j - 1] + 2;
			}
			else {
				dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
			}
		}
	}
	return dp[0][n - 1];        
    }
};

思路二:采用递归的方法进行,思路和上述一样

class Solution {
public:
int longestPalindromeSubseqCore(string &s, vector<vector<int>> &dp, int left, int right) {
	if (dp[left][right] != -1) {
		return dp[left][right];
		
	}
		if (left > right) {
			return 0;
		}
		if (left == right) {
			dp[left][right] = 1;
			return dp[left][right];
		}
		if (s[left] == s[right]) {
			dp[left][right] = longestPalindromeSubseqCore(s, dp, left + 1, right - 1) + 2;
		}
		else {
			dp[left][right] = max(longestPalindromeSubseqCore(s, dp, left + 1, right),longestPalindromeSubseqCore(s, dp, left, right - 1));
		}
		return dp[left][right];
}
int longestPalindromeSubseq(string s) {
	int n = s.size();
	vector<vector<int>> dp(n, vector<int>(n, -1));
	return longestPalindromeSubseqCore(s, dp, 0, n - 1);
}
};





猜你喜欢

转载自blog.csdn.net/qq_26410101/article/details/80857466