005最長迴文子串
阿新 • • 發佈:2020-08-06
寫在前面,參考的力扣官網的題解,動態規劃
一、java程式碼
/* * @lc app=leetcode.cn id=5 lang=java * * [5] 最長迴文子串 */ // @lc code=start class Solution { public String longestPalindrome(String s) { //特殊的判斷,獲得字串長度 int len=s.length(); //如果長度小於2,則直接返回字串 if(len<2){ return s; } //定義最長迴文子串長度,起始位置 int maxLen=1; int begin=0; //dp[i][j]表示s[i..j]是否是迴文串 boolean[][]dp=new boolean[len][len]; //字元本身是迴文子串,所以先把對角線的定義出來 for(int i=0;i<len;i++){ dp[i][i]=true; } //將字串物件中的字元轉換為一個字元陣列 char[] charArray=s.toCharArray(); //先升序填列 for(int j=1;j<len;j++){ //再升序填行 for(int i=0;i<j;i++){ //dp[i][j]=(s[i]==s[j]) and (j-i<3 or dp[i+1][j-1]) //首先改子串的起始位置的字元應該相等 //再看(尾-頭)=0,1,2即<3時直接為true; //若>=3,則轉成子問題,看dp[i+1][j-1] if(charArray[i]!=charArray[j]){ dp[i][j]=false; }else{ if(j-i<3){ dp[i][j]=true; }else{ dp[i][j]=dp[i+1][j-1]; } } //若改子串為迴文串,則判斷是否為最長 if(dp[i][j]&&j-i+1>maxLen){ maxLen=j-i+1; begin=i; } } } //擷取子串substring(int beginIndex, int endIndex) return s.substring(begin,begin+maxLen); } } // @lc code=end
二、動態規劃分析
1、狀態
dp[i][j
]表示子串s[i..j]
是否為迴文子串
2、得到狀態轉移方程
dp[i][j]=(s[i]==s[j]) and dp[i+1][j-1]
--邊界條件 :j-1-(i+1)+1<2
整理得j-i<3
3、初始化
dp[i][i]=true
4、輸出
在得到一個狀態的值為true的時候,記錄起始位置和長度,填表完成後擷取