[英]java longest palindrome not working
我正在開發一個使我回文時間最長的程序:
這是我的代碼,這對於最長的子序列工作正常。 但是我想用另一種方式來做,例如:
havanbava
,我希望結果為avanava
,但是我的程序給了我ava
。 如何解決這個問題。
static void printSubStr(String str, int low, int high) {
System.out.println(str.substring(low, high + 1));
}
static int longestPalindrome(String str) {
int maxLength = 1; // The result (length of LPS)
int start = 0;
int len = str.length();
int low, high;
for (int i = 1; i < len; ++i) {
low = i - 1;
high = i;
while (low >= 0 && high < len && str.charAt(low) == str.charAt(high)) {
if (high - low + 1 > maxLength) {
start = low;
maxLength = high - low + 1;
}
--low;
++high;
}
low = i - 1;
high = i + 1;
while (low >= 0 && high < len && str.charAt(low) == str.charAt(high)) {
if (high - low + 1 > maxLength) {
start = low;
maxLength = high - low + 1;
}
--low;
++high;
}
}
System.out.print("Longest palindrome substring is: ");
printSubStr(str, start, start + maxLength - 1);
return maxLength;
}
考慮到有兩個不同的最長回文序列( avanava和avabava ),您可以迭代找到所有子序列,然后檢查它們是否是回文。 我使用地圖保存所有回文序列及其長度,然后在地圖中循環選擇最長的子序列。 該解決方案只需要第一個最長的(( avanava ):
import java.util.HashMap;
import java.util.Map;
public class Palindrome {
// set to store all the subsequences
static Map<String, Integer> subsequences = new HashMap<>();
public static void main(String[] args) {
subsequence("havanbava");
//storing the higher key/value
Map.Entry<String, Integer> maxEntry = null;
for (Map.Entry<String, Integer> entry : subsequences.entrySet())
{
if (maxEntry == null || entry.getValue().compareTo(maxEntry.getValue()) > 0)
{
maxEntry = entry;
}
}
System.out.println(maxEntry.getKey());
}
static boolean isPalindrome(String str) {
int n = str.length();
for (int i = 0; i < (n/2); ++i) {
if (str.charAt(i) != str.charAt(n - i - 1)) {
return false;
}
}
return true;
}
static void subsequence(String str)
{
for (int i = 0; i < str.length(); i++) {
for (int j = str.length(); j > i; j--) {
String sub_str = str.substring(i, j);
if (!subsequences.containsKey(sub_str)
&& isPalindrome(sub_str))
subsequences.put(sub_str,sub_str.length());
for (int k = 1; k < sub_str.length() - 1; k++) {
StringBuffer sb = new StringBuffer(sub_str);
sb.deleteCharAt(k);
subsequence(sb.toString());
}
}
}
}
}
還請考慮迭代解決方案消耗資源,然后對於長字符串,需要進行一些重大改進。
如果您想要所有最長的子序列(相同長度),這是一個可能的解決方案:
import java.util.HashMap;
import java.util.Map;
public class Palindrome {
// set to store all the subsequences
static Map<String, Integer> subsequences = new HashMap<>();
public static void main(String[] args) {
subsequence("havanbava");
//storing the higher key/value
Map<String, Integer> maxEntries = new HashMap<String, Integer>();
for (Map.Entry<String, Integer> entry : subsequences.entrySet())
{
if (maxEntries.isEmpty()){
maxEntries.put(entry.getKey(),entry.getValue());
}else if(entry.getValue().compareTo( maxEntries.entrySet().iterator().next().getValue() ) == 0)
{
maxEntries.put(entry.getKey(),entry.getValue());
}else if( entry.getValue().compareTo(maxEntries.entrySet().iterator().next().getValue()) > 0){
maxEntries.clear();
maxEntries.put(entry.getKey(),entry.getValue());
}
}
for (Map.Entry<String, Integer> maxEntry : maxEntries.entrySet())
System.out.println(maxEntry.getKey());
}
static boolean isPalindrome(String str) {
int n = str.length();
for (int i = 0; i < (n/2); ++i) {
if (str.charAt(i) != str.charAt(n - i - 1)) {
return false;
}
}
return true;
}
static void subsequence(String str)
{
for (int i = 0; i < str.length(); i++) {
for (int j = str.length(); j > i; j--) {
String sub_str = str.substring(i, j);
if (!subsequences.containsKey(sub_str)
&& isPalindrome(sub_str))
subsequences.put(sub_str,sub_str.length());
for (int k = 1; k < sub_str.length() - 1; k++) {
StringBuffer sb = new StringBuffer(sub_str);
sb.deleteCharAt(k);
subsequence(sb.toString());
}
}
}
}
}
他是一個典型的動態編程問題。 您可以找到最長回文序列 (LPS)的長度, 時間為O(n^2)
。 您應該像這樣構造一個記憶矩陣:
0 1 2 3 4 5 6 7 8 -> indexes
h a v a n b a v a -> input string
0 h 1 1 1 3 3 3 3 5 7 -> max_len = 7 -> a v a b a v a
1 a 0 1 1 3 3 3 3 5 7
2 v 0 0 1 1 1 1 3 5 5
3 a 0 0 0 1 1 1 3 3 3
4 n 0 0 0 0 1 1 1 1 3
5 b 0 0 0 0 0 1 1 1 3
6 a 0 0 0 0 0 0 1 1 3
7 v 0 0 0 0 0 0 0 1 1
8 a 0 0 0 0 0 0 0 0 1
想法是構造一個矩陣,使得matrix[i][j]
(0 <= i,j <= len)等於輸入的第i個索引到第j個索引的LPS。
如果之間的LPS i
和第j
個指數( i<=j
)是LPS(i, j)
具有長度L
:
L=1
我們有: LPS(0,0) = LPS(1,1) = ... = LPS(8,8) = 1
L=2
: LPS(0,1) = LPS(1,2) = ... = LPS(7,8) = 1
(如果input[i]=input[i+1]
, LPS(i,i+1)=2
,即aa
或bb
但我們沒有這種情況) L=3
我們有:
LPS(0,2) = max(LPS(0,1), LPS(1,2)) = max(1, 1) = 1
LPS(1,3) = LPS(1,1) + 2 = 3
更多示例:
LPS(0,4) = max(LPS(0,3), LPS(1,4))=max(3,2) = 3
LPS(2,7) = LPS(3,6) + 2 = 3 + 2 = 5
因此,規則是:
if input[i] != input[j]
LPS(i,j) = max(LPS(i,j-1), LPS(i+1,j))
else
LPS(i,j) = LPS(i+1,j-1) + 2
您可以在這里找到有關LPS的精彩說明。 這個家伙講得很好,我強烈推薦他的動態編程播放列表。 當然,這個問題可以通過遞歸解決方案來解決(就像每個DP問題一樣),但在這里我建議一個示例DP解決方案:
public static String findLPS(String input) {
int len = input.length();
// initializes a diagonal matrix
int[][] matrix = new int[len][len];
for (int i = 0; i < matrix.length; i++) {
matrix[i][i] = 1;
}
// finds the length of the longest palindrome subsequence
for (int jj = 1; jj < len; jj++) {
int i = 0;
int j = jj;
while (i < len && j < len) {
if (input.charAt(i) == input.charAt(j)) {
matrix[i][j] = matrix[i + 1][j - 1] + 2;
} else {
matrix[i][j] = Math.max(matrix[i + 1][j], matrix[i][j - 1]);
}
i++; j++;
}
}
// reconstruct the solution from the matrix
char[] path = new char[len];
int i = 0;
int j = len - 1;
if (matrix[i][j] == 1) {
return input.charAt(0) + "";
}
while (matrix[i][j] != 0) {
if (matrix[i][j] == matrix[i + 1][j]) {
i += 1;
} else if (matrix[i][j] == matrix[i][j - 1]) {
j -= 1;
} else {
path[i] = input.charAt(i);
path[j] = input.charAt(j);
i++; j--;
}
}
String solution = "";
for (int k = 0; k < len; k++) {
if(path[k] != 0) {
solution += path[k];
}
}
return solution;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.