问题
序列s的回文子序列是原序列的子集,元素在原序列中是连续的,回文子序列的前半段和后半段是颠倒的(倒序的前半段与后半段相同)。例如s=[1,2,3,2,1]的回文子序列有
[1,2,3,2,1],[2,3,2],[3],[] 求序列s的最长回文子序列。
解法
设序列s长度为n(数组从1开始,范围[1,n])。设f(i,j)表示s=[i,j]是否为回文子序列,则有状态转移方程:
f(i,j)=⎩⎨⎧truefalsef(i+1,j−1)∧s[i]=s[j](initialize)(initialize)(loop)i,j∈[1,n],i=ji,j∈[1,n],i=j1≤i≤n−1,2≤j≤n (1) 初始化,对于单个元素s[i],显然单个元素可以作为一个最短的回文子序列,即f(i,i)=true,其他则初始化为f(i,j)=false,i=j;
(2) 对于子序列s[i+1,j−1],若其为回文子序列且s[i]=s[j]则扩展后s[i,j]也是回文子序列,若s[i+1][j−1]不是回文子序列或s[i]=s[j]则s[i,j]也不是回文子序列;
遍历所有f(i,j),1≤i≤j≤n找出最大值fmax(imax,jmax),即为最长回文子序列s[imax,jmax]。该算法的时间复杂度为O(n2)。
LeetCode
leetcode-5.cpp
源码
LongestPalindromicSubsequence.h
LongestPalindromicSubsequence.cpp
测试
LongestPalindromicSubsequenceTest.cpp