所說的子串行不一定是連續的,但是順序不變。
子串必須是連續的字元組成。
最優子結構
假設s[i…j]是給定的字串,長度為n,讓dp[i][j]表示從s[i]到s[j]包含的最長回文子串行的長度。
初始化:dp[i][i] = 1;
如果s[i] =s[j],dp[i][j] = dp[i+1][j-1] +2;
如果s[i] != s[j],dp[i][j] = max(dp[i][j-1],dp[i+1][j])
可以得到它的遞迴程式
int lps(char *s ,int i,int j)
重疊子問題
以乙個長度為6的字串為例:
l(1,4)出現重複計算,符合動態規劃的性質。
動態規劃的方法
採用自底向上的方法,將子串行的長度作為排序的依據,按從小到大進行求解。
#include
#include
#include
using
namespace
std;
int max(int i,int j)
int longestpalind(string s)
dp[j][j+i] = temp;}}
result = dp[0][n-1];
//free(dp);
return result;
}int main()
在定義陣列時需要考慮乙個問題,陣列的維數為變數,使用變長陣列(vla)或者是動態分配陣列記憶體(malloc),在c99中加入了對變長陣列的支援,在linux下的g++ 編譯器是支援的,但是在有的編譯器下是非法的,所以最好是通過動態分配記憶體的方法來定義陣列。
變長陣列的特點就是:自動儲存,所用的記憶體空間再執行完定義部分之後會自動釋放。對多維陣列來說更方便。注意使用變長陣列的定義時,如果出現陣列訪問越界,是不會報錯的。
如果使用new來分配記憶體。
int **sp = new
int *[n];
for(i = 0;inew
int[n];
//釋放時
for(i = 0;idelete sp[i];
delete sp;
注意這裡子串是連續的,仍然使用動態規劃的方法。
1.dp[i][j]表示子串s[i…j]是否為回文
2.初始化:dp[i][j] = true (0,n-1);dp[i][i-1] = true(k= 2時使用)。
3.dp[i][j] =(s[i] == s[j] && dp[i+1][j-1] == true)
#include
#include
using
namespace
std;
int lps(string s)
for(i = 2;i<=n;i++)}}
}int result = resright-resleft+1;
return result;
}int main()
方法二:編譯回文子串的中心元素,分別計算偶數長度和奇數長度的回文子串。
#include
#include
using
namespace
std;
int lps(string s)
if(high-low-1 > maxlen) //high-1-(low +1)+1 = len= high-low-1
low = i-1; //以i為中心的回文
high = i+1;
while(low >=0 && high < n && s[low] == s[high])
if(high-low-1 > maxlen)
}return maxlen;
}int main()
動態規劃 最長回文子串行
之前並沒有想過求解 最長回文子串行 的方法,但是自己想想也是沒有什麼好的辦法可以求出 最長回文子串行 來,而最近遇到了一道題目,在經過問題分析,轉化之後,其根本的問題就是 最長回文子串行 的求解問題。題意 兩隻兔子在乙個由n個數字組成的環上,乙隻只能順時針跳,另乙隻只能逆時針跳。跳的規則如下 1 以...
動態規劃之最長回文子串行
15 2 最長回文子串行 回文 palindrome 是正序與逆序相同的非空字串。例如,所有長度為1的字串,civic,racecar,aibohphobia都是回文。設計高效演算法,求給定輸入字串的最長回文子串行。例如,給定輸入character,演算法應該返回carac.演算法的執行時間是怎麼樣...
最長回文子串行 動態規劃
所謂回文字串,就是乙個字串,從左到右讀和從右到左讀是完全一樣的,比如 aba c 對於乙個字串,可以通過刪除某些字元而變成回文字串,如 cabebaf 刪除 c e f 後剩下子串 abba 就是回文字串。要求,給定任意乙個字串,字串最大長度1000,計算出最長的回文子串行長度。如 cabebaf ...