给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢?
输出需要删除的字符个数。
//想了几天,总算学了个皮毛:
//时间 O(n2) 空间 O(n2)
import java.util.Scanner;
public class Main {
//public class NowCoder1 {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
while (s.hasNext()) {
String origin = s.next();
int ans = getMaxLen(origin);
System.out.println(ans);
}
s.close();
}
private static int getMaxLen(String origin) {
//此题跟leetcode求最长回文字串,类似。
int len = origin.length();
int reLen;
int[][] dp = new int[len][len];
//这段要的,跟leetcode不一样。这里计算长度要算是单个字符。
//如果 是 aba,这里的长度要加入b计算,如果是aa,那么就不会用到dp[i][i]
for (int i = 0; i < len; i++) {
dp[i][i] = 1;
}
//注意这里 从 i=j-1 开始,因为忽略非回文并计算长度,填图顺序与leetcode 那题不一样。
for (int j = 1; j < len; j++) {
for (int i = j - 1; i >= 0; i--) {
if (origin.charAt(i) == origin.charAt(j)) {
dp[i][j] = dp[i + 1][j - 1] + 2;
} else {
dp[i][j] = Math.max(dp[i][j - 1], dp[i + 1][j]);
}
}
}
//长度值,在这种顺序填写下,向右上角逐渐合并,所以取 dp[0][len - 1]
reLen = dp[0][len - 1];
return len - reLen;
}
} 面向对象的语言和面向过程的语言限定相同的时间没有可比性,看了一遍基本没有用递归做的java,附上dp迭代的代码
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class DeletePalindrome {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String line;
while ((line = in.readLine()) != null) {
int len = line.length();
int[][] nums = new int[len][len];
char[] line_1 = new char[len];
char[] line_2 = new char[len];
for (int i = 0; i < len; i++) {
line_1[i] = line.charAt(i);
line_2[i] = line.charAt(len - 1 - i);
}
int i = 0;
while (i < len) {
if (line_1[0] != line_2[i]) {
nums[i][0] = 0;
} else {
while (i < len) {
nums[i][0] = 1;
i++;
}
break;
}
i++;
}
i = 0;
while (i < len) {
if (line_2[0] != line_1[i]) {
nums[0][i] = 0;
} else {
while (i < len) {
nums[0][i] = 1;
i++;
}
break;
}
i++;
}
for (int i_index = 1; i_index < len; i_index++) {
for (int j_index = 1; j_index < len; j_index++) {
if (line_1[j_index] == line_2[i_index]) {
nums[i_index][j_index] = nums[i_index - 1][j_index - 1] + 1;
} else {
nums[i_index][j_index] = Math.max(nums[i_index][j_index - 1], nums[i_index - 1][j_index]);
}
}
}
System.out.println(len - nums[len - 1][len - 1]);
}
}
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
while (scan.hasNext()) {
String str = scan.nextLine();
String reverseStr = new StringBuilder(str).reverse().toString();
System.out.println(str.length() - lcs(str, reverseStr));
}
}
// 求最长公共子串长度 Longest Common Subsequence LCS算法
private static int lcs(String str, String reverseStr) {
// TODO Auto-generated method stub
int len1 = str.length();
int len2 = reverseStr.length();
int result = 0;// 记录下最长公共子串长度
int[][] c = new int[len1 + 1][len2 + 1];
for (int i = 0; i < len1; i++) {
for (int j = 0; j < len2; j++) {
if (str.charAt(i) == reverseStr.charAt(j)) {
c[i + 1][j + 1] = c[i][j] + 1;
} else {
c[i + 1][j + 1] = Math.max(c[i][j + 1], c[i + 1][j]);
}
}
}
return c[len1][len2];
}
}
import java.util.*;
public class Main{
public static void main(String[] arg){
Scanner input = new Scanner(System.in);
while(input.hasNextLine()){
String s = input.nextLine();
char[] c = s.toCharArray();
intlen = c.length;
int[][] state = new int[len+1][len+1];
state[0][0] = 0;
for(int i = 0; i < len; i++){ //正序的每一个字符同反序的每一个字符比较
for(int j = 0; j < len; j++){
if(c[i] == c[len-1-j]) state[i+1][j+1] = state[i][j] + 1; //字符是相同的 则前一个字符相同的数加一
else state[i+1][j+1] = Math.max(state[i+1][j],state[i][j+1]); //对应的字符不相同 则取前面相同字符数中最大那个
//这样得到就是相同字符数最多的值 就是回文的长度 总长减去此长 就得到要删减的数目
}
}
System.out.println(len - state[len][len]);
}
}
}
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
String s1 = sc.next();
String s2 = new StringBuilder(s1).reverse().toString();
int[][] dp = new int[s1.length() + 1][s2.length() + 1];
for (int i = 1; i < dp.length; i ++ ) {
for (int j = 1; j < dp[0].length; j ++ ) {
dp[i][j] = s1.charAt(i - 1) == s2.charAt(j - 1) ? dp[i - 1][j - 1] + 1 : Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
System.out.println(s1.length() - dp[s1.length()][s2.length()]);
}
}
}
import java.util.Scanner;
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while(in.hasNext()){
String str = in.nextLine();
System.out.println(L(str));
}
}
public static int L(String str){
String strL = new StringBuffer(str).reverse().toString();//字符串反转
int len = str.length();
int map[][] = new int[len+1][len+1];
for(int i=0;i<len;i++){
for(int j=0;j<len;j++){
map[i][j] = 0;
}
}
for(int i=0;i<len;i++){
for(int j=0;j<len;j++){
if(str.charAt(i)==strL.charAt(j)){
map[i+1][j+1] = map[i][j]+1;
}else{
map[i+1][j+1] = Math.max(map[i][j+1], map[i+1][j]);
}
}
}
return len-map[len][len];//map[len][len]保存的是最大公共子串的长度
}
}