给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢?
回文串的特点:把一个字符串反过来跟原字符串一样,比如 abcba 反过来还是abcba
题目中要求删除一些字符,剩下的为回文串,也就是说可以是不连续的。可以转换为最长公共子序列的问题,即将字符串s反转为s1,求s和s1的最长公共子序列。 比如 google 反转过来为 elgoog 最长公共子序列为goog。
求 google 和 elgoog的最长公共子序列可以借助动态规划的思想,一步步来求。
定义长度为length+1的二维数组,[i,j]表示 s的前i项和s1的前j项的最长公共子序列。
上图就是构建的状态矩阵,第[ 2,3 ]项表示 s字符串从 0-1 的字串与 s1字符串从0-2的字串的最长公共子序列,即"go"和"elg"的最长公共子串,计算方法为,首先比较s的第2个字符和s1的第三个字符是否相等,如果相等,最长字串是两个字串往前一位的字串的最长公共部分+1。如果不相等,则最长的为s的i-1 和s1的j的最长和s的i位和s1的j-1位最长中更大的一个。
代码如下:
import java.util.Scanner;
import java.lang.StringBuilder;
import java.lang.Math;
public class Main{
public static void main(String[] args)
{
Scanner in =new Scanner(System.in);
while(in.hasNext())
{
String s = in.nextLine();
String s1 =new StringBuilder(s).reverse().toString();
int[][] arr = new int[s.length()+1][s.length()+1];
for(int a=1;a<=s.length();a++)
{
for(int b=1;b<=s.length();b++)
{
if(s.charAt(a-1)==s1.charAt(b-1))
{
arr[a][b]=arr[a-1][b-1]+1;
}
else
{
arr[a][b]=Math.max(arr[a-1][b],arr[a][b-1]);
}
}
}
System.out.println(s.length()-arr[s.length()][s.length()]);
}
}
}