調試以下問題(遞歸解決方案)並混淆for循環的邏輯含義是什麼。如果有人有任何見解,讚賞分享。最短的迴文遞歸解決方案問題
給定一個字符串S,您可以通過在其前面添加字符將其轉換爲迴文。通過執行此轉換,查找並返回可找到的最短迴文。
例如:
鑑於 「aacecaaa」,迴歸 「aaacecaaa」。
給定「abcd」,返回「dcbabcd」。
int j = 0;
for (int i = s.length() - 1; i >= 0; i--) {
if (s.charAt(i) == s.charAt(j)) { j += 1; }
}
if (j == s.length()) { return s; }
String suffix = s.substring(j);
return new StringBuffer(suffix).reverse().toString() + shortestPalindrome(s.substring(0, j)) + suffix;
基於KMP的解決方案,
public class Solution {
public String shortestPalindrome(String s) {
String p = new StringBuffer(s).reverse().toString();
char pp[] = p.toCharArray();
char ss[] = s.toCharArray();
int m = ss.length;
if (m == 0) return "";
// trying to find the greatest overlap of pp[] and ss[]
// using the buildLPS() method of KMP
int lps[] = buildLPS(ss);
int i=0;// points to pp[]
int len = 0; //points to ss[]
while(i<m) {
if (pp[i] == ss[len]) {
i++;
len++;
if (i == m)
break;
} else {
if (len == 0) {
i++;
} else {
len = lps[len-1];
}
}
}
// after the loop, len is the overlap of the suffix of pp and prefix of ss
return new String(pp) + s.substring(len, m);
}
int [] buildLPS(char ss[]) {
int m = ss.length;
int lps[] = new int[m];
int len = 0;
int i = 1;
lps[0] = 0;
while(i < m) {
if (ss[i] == ss[len]) {
len++;
lps[i] = len;
i++;
} else {
if (len == 0) {
i++;
} else {
len = lps[len-1];
}
}
}
return lps;
}
}
在此先感謝, 林
感謝@StuartLC的實現,瞭解j的邏輯意義當字符串本身是Palindrome時,我的問題更多的是關於字符串本身何時不是Palindrome,j的邏輯意義是什麼。似乎j總是用於進一步遞歸,不管是哪種情況。任何見解都值得讚賞。 :) –
由於代碼片段沒有評論,所以是錯誤的。該循環假定從字符串的末尾開始在相同的\t連續排列中遇到的每個字符都處於合適的中間索引之前 - 猜測。 (給'acea'試一下,或'acacia'。) – greybeard
@greybeard,我發佈了一個基於KMP的解決方案,您如何看待它?現在更乾淨和邏輯正確嗎?謝謝。 :) –