Algorithm 如何找到最长回文子序列?
这里是算法书(Vazirani)中的问题(6.7),与经典问题略有不同。我怎样才能解决这个问题 如果子序列是回文序列,则该子序列是回文序列 无论从左向右还是从左向右读取,都相同 从右到左。例如 序列Algorithm 如何找到最长回文子序列?,algorithm,dynamic-programming,palindrome,Algorithm,Dynamic Programming,Palindrome,这里是算法书(Vazirani)中的问题(6.7),与经典问题略有不同。我怎样才能解决这个问题 如果子序列是回文序列,则该子序列是回文序列 无论从左向右还是从左向右读取,都相同 从右到左。例如 序列 A,C,G,T,G,T,C,A,A,A,A,T,C,G 有许多回文子序列, 包括A,C,G,C,A和A,A,A (另一方面,子序列 A,C,T不是回文)。设计 采用序列x[1]的算法 …n]并返回(长度) 最长回文子序列。它的 运行时间应为O(n^2) 对于字符串中的每个字母: 将字母设置为回文
A,C,G,T,G,T,C,A,A,A,A,T,C,G
有许多回文子序列,
包括A,C,G,C,A
和A,A,A
(另一方面,子序列
A,C,T
不是回文)。设计
采用序列x[1]的算法
…n]
并返回(长度)
最长回文子序列。它的
运行时间应为O(n^2)
对于字符串中的每个字母:
- 将字母设置为回文的中间部分(当前长度=1)
- 如果这是回文的中间部分,请检查回文的长度
- 如果这个回文比我们发现的长(到目前为止):保留索引和回文的大小
x[i…j]
中构建最长回文子序列,使用x[i+1…j]
、x[i,…j-1]
和x[i+1,…,j-1]
的最长子序列(如果首字母和末字母相同)
首先,空字符串和单个字符串通常是回文。
注意,对于子字符串x[i,…,j]
,如果x[i]==x[j]
,我们可以说最长回文的长度是x[i+1,…,j-1]+2上的最长回文。如果它们不匹配,则最长回文是x[i+1,…,j]
和y[i,…,j-1]
的最大回文
这为我们提供了以下功能:
longest(i,j)= j-i+1 if j-i<=0,
2+longest(i+1,j-1) if x[i]==x[j]
max(longest(i+1,j),longest(i,j-1)) otherwise
最长(i,j)=j-i+1,如果j-i输入:A1,A2,…,An
目标:找到最长的严格递增子序列(不一定是连续的).
L(j):最长严格递增子序列,以j结尾
L(j):max{L(i)}+1},其中i
然后为所有j查找max{L(j)}
您将获得最长回文序列的源代码
public class LongestPalindrome
{
int max(int x , int y)
{
return (x>y)? x:y;
}
int lps(char[] a ,int i , int j)
{
if(i==j) //If only 1 letter
{
return 1;
}
if(a[i] == a[j] && (i+1) == j) // if there are 2 character and both are equal
{
return 2;
}
if(a[i] == a[j]) // If first and last char are equal
{
return lps(a , i+1 , j-1) +2;
}
return max(lps(a,i+1 ,j),lps(a,i,j-1));
}
public static void main(String[] args)
{
String s = "NAMAN IS NAMAN";
LongestPalindrome p = new LongestPalindrome();
char[] c = s.toCharArray();
System.out.print("Length of longest seq is" + p.lps(c,0,c.length-1));
}
}
子串和子序列之间的区别让我有点困惑。(参见Ex6.8和6.11)根据我们对子序列的理解,给出的示例没有回文子序列ACGCA。
这是我的伪代码,我不太确定初始化>这个问题也可以作为一个非常常见的问题LCS(最长公共子序列)问题的变体来解决。
让输入字符串由字符数组s1[0…n-1]表示
1) 反转给定的序列,并将反转存储在另一个数组中,比如s2[0..n-1],其实质是s1[n-1..0]
2) 给定序列s1和反向序列s2的LCS将是最长的回文序列
此溶液也是O(n^2)溶液 导入java.util.HashSet
导入java.util.Scanner
/**
*@param args
*给我们一个字符串,我们需要找到该字符串中最长的子序列,即回文序列
*在这段代码中,我们使用hashset来确定给定字符串中唯一的子字符串集
*/
公共类NumberOfPalindrome{
/**
* @param args
* Given a string find the longest possible substring which is a palindrome.
*/
public static HashSet<String> h = new HashSet<>();
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
for(int i=0;i<=s.length()/2;i++)
h.add(s.charAt(i)+"");
longestPalindrome(s.substring(0, (s.length()/2)+(s.length()%2)));
System.out.println(h.size()+s.length()/2);
System.out.print(h);
}
public static void longestPalindrome(String s){
//System.out.println(s);
if(s.length()==0 || s.length()==1)
return;
if(checkPalindrome(s)){
h.add(s);
}
longestPalindrome(s.substring(0, s.length()-1));
longestPalindrome(s.substring(1, s.length()));
}
public static boolean checkPalindrome(String s){
//System.out.println(s);
int i=0;int j=s.length()-1;
while(i<=j){
if(s.charAt(i)!=s.charAt(j))
return false;
i++;j--;
}
return true;
}
}
/**
*@param args
*给定一个字符串,找到可能最长的子字符串,即回文。
*/
公共静态HashSet h=新HashSet();
公共静态void main(字符串[]args){
扫描仪sc=新的扫描仪(System.in);
字符串s=sc.nextLine();
对于(int i=0;iprivate static int findLongestPalindromicSubsequence(String字符串){
int stringLength=string.length();
int[][]l=新int[stringLength][stringLength];
用于(int-length=1;length程序从给定字符串中查找最长回文子字符串。
package source;
import java.util.ArrayList;
public class LongestPalindrome
{
//Check the given string is palindrome by
public static boolean isPalindrome (String s)
{
StringBuffer sb = new StringBuffer(s);
if(s.equalsIgnoreCase(sb.reverse().toString()))
return true;
else
return false;
}
public static void main(String[] args)
{
//String / word without space
String str = "MOMABCMOMOM"; // "mom" //"abccbabcd"
if(str.length() > 2 )
{
StringBuffer sb = new StringBuffer();
ArrayList<String> allPalindromeList = new ArrayList<>();
for(int i=0; i<str.length(); i++)
{
for(int j=i; j<str.length(); j++)
{
sb.append(str.charAt(j));
if( isPalindrome(sb.toString()) ) {
allPalindromeList.add(sb.toString());
}
}
//clear the stringBuffer
sb.delete(0, sb.length());
}
int maxSubStrLength = -1;
int indexMaxSubStr = -1;
int index = -1;
for (String subStr : allPalindromeList) {
++index;
if(maxSubStrLength < subStr.length()) {
maxSubStrLength = subStr.length();
indexMaxSubStr = index;
}
}
if(maxSubStrLength > 2)
System.out.println("Maximum Length Palindrome SubString is : "+allPalindromeList.get(indexMaxSubStr));
else
System.out.println("Not able to find a Palindrome who is three character in length!!");
}
}
}
包源;
导入java.util.ArrayList;
公共类最长回文
{
//通过检查给定字符串是否为回文
公共静态布尔值isAlindrome(字符串s)
{
StringBuffer sb=新的StringBuffer;
如果(s.equalsIgnoreCase(sb.reverse().toString()))
返回true;
其他的
返回false;
}
公共静态void main(字符串[]args)
{
//不带空格的字符串/单词
字符串str=“momabcomom”;/“mom”//“abccbabcd”
如果(str.length()>2)
{
StringBuffer sb=新的StringBuffer();
ArrayList allPalindromeList=新建ArrayList();
对于(int i=0;这个问题要求的是最长的回文子序列,而不是子字符串。这意味着字符串中的字母不需要是连续的。我认为当它们匹配时应该是2+…
,如果j-i这是一个O(n^2)算法,那么j-i?n的输入不是不同的吗
private static int findLongestPalindromicSubsequence(String string) {
int stringLength = string.length();
int[][] l = new int[stringLength][stringLength];
for(int length = 1; length<= stringLength; length++){
for(int left = 0;left<= stringLength - length;left++){
int right = left+ length -1;
if(length == 1){
l[left][right] = 1;
}
else{
if(string.charAt(left) == string.charAt(right)){
//L(0, n-1) = L(1, n-2) + 2
if(length == 2){
// aa
l[left][right] = 2;
}
else{
l[left][right] = l[left+1][right-1]+2;
}
}
else{
//L(0, n-1) = MAX ( L(1, n-1) , L(0, n-2) )
l[left][right] = (l[left+1][right] > l[left][right-1])?l[left+1][right] : l[left][right-1];
}
}
}
}
return l[0][stringLength-1];
}
package source;
import java.util.ArrayList;
public class LongestPalindrome
{
//Check the given string is palindrome by
public static boolean isPalindrome (String s)
{
StringBuffer sb = new StringBuffer(s);
if(s.equalsIgnoreCase(sb.reverse().toString()))
return true;
else
return false;
}
public static void main(String[] args)
{
//String / word without space
String str = "MOMABCMOMOM"; // "mom" //"abccbabcd"
if(str.length() > 2 )
{
StringBuffer sb = new StringBuffer();
ArrayList<String> allPalindromeList = new ArrayList<>();
for(int i=0; i<str.length(); i++)
{
for(int j=i; j<str.length(); j++)
{
sb.append(str.charAt(j));
if( isPalindrome(sb.toString()) ) {
allPalindromeList.add(sb.toString());
}
}
//clear the stringBuffer
sb.delete(0, sb.length());
}
int maxSubStrLength = -1;
int indexMaxSubStr = -1;
int index = -1;
for (String subStr : allPalindromeList) {
++index;
if(maxSubStrLength < subStr.length()) {
maxSubStrLength = subStr.length();
indexMaxSubStr = index;
}
}
if(maxSubStrLength > 2)
System.out.println("Maximum Length Palindrome SubString is : "+allPalindromeList.get(indexMaxSubStr));
else
System.out.println("Not able to find a Palindrome who is three character in length!!");
}
}
}