给定一个字符串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]保存的是最大公共子串的长度 } }