leetcode5:最長迴文子串
阿新 • • 發佈:2018-11-11
1 題目
給定一個字串 s,找到 s 中最長的迴文子串。你可以假設 s 的最大長度為1000。
示例 1:
輸入: “babad”
輸出: “bab”
注意: "aba"也是一個有效答案。
示例 2:
輸入: “cbbd”
輸出: “bb”
題目連結:
https://leetcode-cn.com/problems/longest-palindromic-substring/description/
2 解法
2.1 中心擴充套件法
class Solution { public: string longestPalindrome(string s) { if(s == NULL || s.size() <= 1) return s; int start = 0; int end = 0; for(int i = 0; i < s.size(); i++){ int len1 = maxlen(s,i,i); int len2 = maxlen(s,i,i+1); int len = len1 > len2 ? len1 : len2; //cout<<"len:"<<len<<endl; if(len > end - start){ # 新的子串餘當前子串長度相等就更新,如果有幾個相同長度的子串,找出的是最後一個;如果寫成if(len > end - start),則新的子串大於當前子串長度才更新,如果有幾個相同長度的子串,找出的是最前一個 //cout<<"start:"<<start<<" end:"<<end<<endl; start = i - (len - 1)/2; end = i + len / 2; } } return s.substr(start,end-start+1); } int maxlen(string s,int i,int j){ int left= i; int right=j; while(left >= 0 && right < s.size() && s[left] == s[right]){ left--; right++; } return right - left - 1; } };
2.2 動態規劃法
class Solution { public: string longestPalindrome(string s) { if(s.size() == 0) return s; const int n=s.size(); bool dp[n][n]; fill_n(&dp[0][0],n*n,false); int max_len=1; //儲存最長迴文子串長度 int start=0;//儲存最長迴文子串起點 for(int i=0;i<s.size();++i) { for(int j=0;j<=i;++j) { if(i-j<2) dp[j][i]=(s[i]==s[j]); else dp[j][i]=(s[i]==s[j] && dp[j+1][i-1]); if(dp[j][i] && max_len<(i-j+1)) { max_len=i-j+1; start=j; } } } return s.substr(start,max_len); } };
解析:迴文串就是正著讀和反著讀一樣的字串,如“abba”,“abcba”,最長迴文子串是字串的子串中最長的屬於迴文串的子串。如字串"abbaabccba"的最長迴文子串為"abccba",本文采用動態規劃演算法來查詢最長迴文子串,演算法時間複雜度為O(n²)。**設狀態dp[j][i]表示索引j到索引i的子串是否是迴文串。**則易得轉移方程如下:
則dp[j][i]為true時表示索引j到索引i形成的子串為迴文子串,且子串起點索引為i,長度為j+i-1。
2.3 暴力求解法
暴力求解就是列舉出s的左右子串,判斷是否是迴文子串,如果是判斷其長度是否大於找到的上一個迴文子串,大於則更新否則不更新。
參考部落格:動態規劃演算法求最長迴文子串