1. 程式人生 > >【LeetCode】5. 最長迴文子串 結題報告 (C++)

【LeetCode】5. 最長迴文子串 結題報告 (C++)

題目描述:

給定一個字串 s,找到 s 中最長的迴文子串。你可以假設 的最大長度為1000。

示例 1:

輸入: "babad"
輸出: "bab"
注意: "aba"也是一個有效答案。

示例 2:

輸入: "cbbd"
輸出: "bb"
解題方法:不會做,從網上扒的程式碼。學習。
string longestPalindromeDP(string s) {
  int n = s.length();
  int longestBegin = 0;
  int maxLen = 1;
  bool table[1000][1000] = {false};
  for (int i = 0; i < n; i++) {
    table[i][i] = true;
  }
  for (int i = 0; i < n-1; i++) {
    if (s[i] == s[i+1]) {
      table[i][i+1] = true;
      longestBegin = i;
      maxLen = 2;
    }
  }
  for (int len = 3; len <= n; len++) {
    for (int i = 0; i < n-len+1; i++) {
      int j = i+len-1;
      if (s[i] == s[j] && table[i+1][j-1]) {
        table[i][j] = true;
        longestBegin = i;
        maxLen = len;
      }
    }
  }
  return s.substr(longestBegin, maxLen);
}

時間複雜度為f O(N2) ,空間複雜度也為f O(N2) 。table二維陣列是精髓,記錄每個字元是否和後繼字元相同。該方法先對一位和兩位字串進行判斷,更新table二維陣列,再對長度為三以上的字元進行判斷,對陣列進行更新。

longestBegin和maxLen的用法也值得學習:

basic_string::substrbasic_string substr(size_type _Off = 0,size_type _Count = npos) const;引數_Off所需的子字串的起始位置。字元串中第一個字元的索引為 0,預設值為0._Count複製的字元數目返回值一個子字串,從其指定的位置開始
  1. string x="Hello_World"
    ;  
  2.     /*預設擷取從0到npos.過載原型為string substr(_off=0,_count=npos);npos一般表示為string類中不存在的位置,_off表示字串的開始位置,_count擷取的字元的數目*/
  3.     cout<<x.substr()<<endl;  
  4.     cout<<x.substr(5)<<endl;//擷取x[5]到結尾,即npos.過載原型為string substr(_off,_count=npos)
  5.     cout<<x.substr(0,5)<<endl;//以x[0]為始,向後擷取5位(包含x[0]),過載原型string substr(_off,_count)

優化方法:

string expandAroundCenter(string s, int c1, int c2) {
  int l = c1, r = c2;
  int n = s.length();
  while (l >= 0 && r <= n-1 && s[l] == s[r]) {
    l--;
    r++;
  }
  return s.substr(l+1, r-l-1);
}
 
string longestPalindromeSimple(string s) {
  int n = s.length();
  if (n == 0) return "";
  string longest = s.substr(0, 1);  // a single char itself is a palindrome
  for (int i = 0; i < n-1; i++) {
    string p1 = expandAroundCenter(s, i, i);
    if (p1.length() > longest.length())
      longest = p1;
 
    string p2 = expandAroundCenter(s, i, i+1);
    if (p2.length() > longest.length())
      longest = p2;
  }
  return longest;
}
i代表測試字串的下標,對字串進行遍歷,傳回迴旋字串。這種遍歷要進行兩次,因為考慮到奇數個迴旋和偶數個迴旋。