【LeetCode Hot 100 最長迴文子串】

新年的刷的第一題,題目以下:算法

給你一個字符串 s,找到 s 中最長的迴文子串。網絡

 

示例 1:函數

輸入:s = "babad"
輸出:"bab"
解釋:"aba" 一樣是符合題意的答案。
示例 2:ui

輸入:s = "cbbd"
輸出:"bb"
示例 3:spa

輸入:s = "a"
輸出:"a"
示例 4:code

輸入:s = "ac"
輸出:"a"
 blog

提示:leetcode

1 <= s.length <= 1000
s 僅由數字和英文字母(大寫和/或小寫)組成字符串

來源:力扣(LeetCode)
連接:https://leetcode-cn.com/problems/longest-palindromic-substring
著做權歸領釦網絡全部。商業轉載請聯繫官方受權,非商業轉載請註明出處。get

 

初始思路:

剛開始的想法是想每一個字符開始向左右進行拓展,將所有的字符循環一遍,最後就能夠找到最長的迴文字符串。但本身感受這種方法時間複雜度過高了,就沒往下想了,唉,太不自信了。

答案思路:

答案寫的很是詳細,分了三種方法,第三種不講,有點複雜,首先要說的是和本身初始子路相似的解法-中心擴展算法,廢話很少說,直接上代碼:

 

class Solution {
public:
    pair<int,int> getLongest(string & s,int left,int right)
    {
     /*注意這裏是while循環,會一直向外擴展,知道找到當前字符對應的最長迴文串。*/
while(left>=0&&right<s.size()&&s[left]==s[right]) { left--; right++; }
     /*對pair的用法不熟悉,還沒想過能夠這樣用*/
return {left+1,right-1}; } string longestPalindrome(string s) { int start=0,end=0;
     /*看這裏,這個for循環,將每一個字符都進行遍歷*/
for(int i=0;i<s.size();i++) {
       /*感受很困惑吧,爲啥要將getLongest函數調用兩次,我簡單的理解爲奇數長度和偶數長度迴文串兩種狀況。*/ auto [left1,right1]
=getLongest(s,i,i); auto [left2,right2]=getLongest(s,i,i+1); if(right1-left1>end-start) { start=left1; end=right1; } if(right2-left2>end-start) { start=left2; end=right2; } }
     /*返回最長的迴文字符串,答案不惟一*/
return s.substr(start,end-start+1); } };

 

答案中介紹的第二種方法是動態規劃,直接看代碼:

class Solution {
public:
    string longestPalindrome(string s) {
        vector<vector<int>> dp(n, vector<int>(n));string strReturn="";
     /*從長度1開始,一直到s.size(),注意不要被0誤導*/
for(int len=0;len<s.size();len++) {
       /*每種長度下的字符都遍歷一遍賦值*/
for(int i=0;i<s.size()-len;i++) {
          /*對應的是字符本身*/
if(len==0) { dp[i][i]=1; }
          /*長度1的狀況*/
else if(len==1) { dp[i][i+len]=s[i]==s[i+len]; }
          /*其餘狀況*/
else { dp[i][i+len]=dp[i+1][i+len-1]&&(s[i]==s[i+len]); } if(dp[i][i+len]&&len+1>strReturn.size()) { strReturn=s.substr(i,len+1); } } } return strReturn; } };

 

兩種算法的時間和空間複雜度對好比下:

        時間複雜度    空間複雜度

中心擴展算法:    O(n*n)                  O(1)

動態規劃:   O(n*n)     O(n*n)

相關文章
相關標籤/搜索