題目描述
Catcher是MCA國的情報員,他工做時發現敵國會用一些對稱的密碼進行通訊,好比像這些ABBA,ABA,A,123321,
可是他們有時會在開始或結束時加入一些無關的字符以防止別國破解。好比進行下列變化 ABBA->12ABBA,ABA->ABAKK,
123321->51233214 。由於截獲的串太長了,並且存在多種可能的狀況(abaaab可看做是aba,或baaab的加密形式),
Cathcer的工做量實在是太大了,他只能向電腦高手求助,你能幫Catcher找出最長的有效密碼串嗎?
輸入描述
輸入一個字符串
輸出描述
返回有效密碼串的最大長度
輸入例子
ABBA
輸出例子
4
算法實現
import java.util.Scanner;
/**
* All Rights Reserved !!!
*/
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Scanner scanner = new Scanner(Main.class.getClassLoader().getResourceAsStream("data.txt"));
while (scanner.hasNext()) {
String input = scanner.nextLine();
System.out.println(longestPalindrome(input));
}
scanner.close();
}
/**
* 這道題本質是求字符串中的最大回文字串的長度
* 動態規劃法,
* 假設dp[ i ][ j ]的值爲true,表示字符串s中下標從 i 到 j 的字符組成的子串是迴文串。那麼能夠推出:
* dp[ i ][ j ] = dp[ i + 1][ j - 1] && s[ i ] == s[ j ]。
* 這是通常的狀況,因爲須要依靠i+1, j -1,因此有可能 i + 1 = j -1, i +1 = (j - 1) -1,
* 所以須要求出基準狀況才能套用以上的公式:
* a. i + 1 = j -1,即迴文長度爲1時,dp[ i ][ i ] = true;
* b. i +1 = (j - 1) -1,即迴文長度爲2時,dp[ i ][ i + 1] = (s[ i ] == s[ i + 1])。
* 有了以上分析就能夠寫出代碼了。須要注意的是動態規劃須要額外的O(n^2)的空間。
*
* @param s 待求字符串
* @return 最大回文字串的長度
*/
private static int longestPalindrome(String s) {
// 不考慮非法輸入的狀況,好比null
int maxLen = 0;
int len = s.length();
boolean[][] t = new boolean[len][len];
// 單個字符串都是迴文
for (int i = 0; i < len; i++) {
t[i][i] = true;
maxLen = 1;
}
for (int i = 0; i < len - 1; i++) {
if (s.charAt(i) == s.charAt(i + 1)) {
t[i][i + 1] = true;
maxLen = 2;
}
}
// 求長度大於2的子串是不是迴文串
for (int gap = 3; gap <= len; gap++) {
for (int i = 0, j; (j = i + gap - 1) <= len - 1; i++) {
if (s.charAt(i) == s.charAt(j)) {
t[i][j] = t[i+1][j-1];
if (t[i][j] && gap > maxLen) {
maxLen = gap;
}
} else {
t[i][j] = false;
}
}
}
return maxLen;
}
}