题目描述

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

来源,leetcode 每日一题 5. 最长回文子串

例如:

  1. 输入: "babad"
  2. 输出: "bab"
  3. 注意: "aba" 也是一个有效答案。

解题思路

  1. If “aba” is a palindrome, is “xabax” and palindrome? Similarly is “xabay” a palindrome?
  2. 中心向外扩展。

    manacher解法

    https://leetcode-cn.com/problems/longest-palindromic-substring/solution/zui-chang-hui-wen-zi-chuan-by-leetcode-solution/

代码

  1. class Solution {
  2. public:
  3. int expand(const string& s, int left, int right) {
  4. while (left >= 0 && right < s.size() && s[left] == s[right]) {
  5. --left;
  6. ++right;
  7. }
  8. return (right - left - 2) / 2;
  9. }
  10. string longestPalindrome(string s) {
  11. int start = 0, end = -1;
  12. string t = "#";
  13. for (char c: s) {
  14. t += c;
  15. t += '#';
  16. }
  17. t += '#';
  18. s = t;
  19. vector<int> arm_len;
  20. int right = -1, j = -1;
  21. for (int i = 0; i < s.size(); ++i) {
  22. int cur_arm_len;
  23. if (right >= i) {
  24. int i_sym = j * 2 - i;
  25. int min_arm_len = min(arm_len[i_sym], right - i);
  26. cur_arm_len = expand(s, i - min_arm_len, i + min_arm_len);
  27. } else {
  28. cur_arm_len = expand(s, i, i);
  29. }
  30. arm_len.push_back(cur_arm_len);
  31. if (i + cur_arm_len > right) {
  32. j = i;
  33. right = i + cur_arm_len;
  34. }
  35. if (cur_arm_len * 2 + 1 > end - start) {
  36. start = i - cur_arm_len;
  37. end = i + cur_arm_len;
  38. }
  39. }
  40. string ans;
  41. for (int i = start; i <= end; ++i) {
  42. if (s[i] != '#') {
  43. ans += s[i];
  44. }
  45. }
  46. return ans;
  47. }
  48. };