1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| #include <iostream> #include <string> #include <vector>
using namespace std;
class Solution { public: string longestPalindrome(string s) { int n = s.size(); if (n < 2) { return s; }
int maxLen = 1; int begin = 0; // dp[i][j] 表示 s[i..j] 是否是回文串 vector<vector<int>> dp(n, vector<int>(n)); // 初始化:所有长度为 1 的子串都是回文串 for (int i = 0; i < n; i++) { dp[i][i] = true; } // 递推开始 // 先枚举子串长度 for (int L = 2; L <= n; L++) { // 枚举左边界,左边界的上限设置可以宽松一些 for (int i = 0; i < n; i++) { // 由 L 和 i 可以确定右边界,即 j - i + 1 = L 得 int j = L + i - 1; // 如果右边界越界,就可以退出当前循环 if (j >= n) { break; }
if (s[i] != s[j]) { dp[i][j] = false; } else { if (j - i < 3) { dp[i][j] = true; } else { dp[i][j] = dp[i + 1][j - 1]; } }
// 只要 dp[i][L] == true 成立,就表示子串 s[i..L] 是回文,此时记录回文长度和起始位置 if (dp[i][j] && j - i + 1 > maxLen) { maxLen = j - i + 1; begin = i; } } } return s.substr(begin, maxLen); } };
// 真-中心扩散 class Solution { public: pair <int, int> f(const string& s, int l, int r){ while(l >= 0 && r < s.size() && s[l] == s[r]){ l --; r ++; } return {l + 1, r - 1}; } string longestPalindrome(string s) { int n = s.size(); if(n < 1){ return ""; } int st = 0, ed = 0; for(int i = 0; i < n; ++i){ const auto &[l1, r1] = f(s, i, i); const auto &[l2, r2] = f(s, i, i + 1); cout << i << ' ' << l1 << ' ' << r1 << ' ' << l2 << ' ' << r2 << endl; // auto [l1, r1] = f(s, i, i); // auto [l2, r2] = f(s, i, i + 1); if((r1 - l1 + 1) > (ed - st + 1)){ st = l1; ed = r1; } if(r2 - l2 + 1 > ed - st + 1){ st = l2; ed = r2; } } return s.substr(st, ed - st + 1); } };
|