leetcode

5. Longest Palindromic Substring

2020-06-09  本文已影响0人  syuhung

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of sis 1000.

Example 1:
Input: "babad"
Output: "bab"
Note: "aba" is also a valid answer.

Example 2:
Input: "cbbd"
Output: "bb"

hint1:
How can we reuse a previously computed palindrome to compute a larger palindrome?

hint2:
If “aba” is a palindrome, is “xabax” and palindrome? Similarly is “xabay” a palindrome?

hint3:
Complexity based hint:
If we use brute-force and check whether for every start and end position a substring is a palindrome we have O(n^2) start - end pairs and O(n) palindromic checks. Can we reduce the time for palindromic checks to O(1) by reusing some previous computation.


题目大意:

  给定一个字符串s,找出它的最长回文子串,字符串s的长度不超过1000。

解题思路:

  首先分析题目返回值,和昨天的找出最长子串的长度不一样,这个是要找出长串,也就意味着要么把最长子串的长度和开始下表记录下来,要么得另外找容器记录最长子串。
  来看题目要求,找出最长回文子串,两个限定,回文和最长。第一想法简单的就是找出所有回文子串存到某个容器中,再输出长度最长的即可,但这样无疑效率是最低的,而且题目有提示可以尝试O(1)时间复杂度内解决。
  O(1)时间复杂度解决,那么很明显字符串只遍历了一次,我开始想的是前后设置一个指针逐步往中间逼近,但是发现这样做的复杂度还是O(n^2),再看看提示2,其实可以从中间散开而不是从两边逐渐逼近。

解题代码:


class Solution {
public:
    string longestPalindrome(string s)
    {
        /*边界情况检查*/
        if (s.size() < 2)
            return s;
        /*
        left                        :左指针
        right                       :右指针
        flag                        :哨兵,用来表示遍历过程中最新位置
        max_s                       :最长回文子串长度
        max_l                       :最长回文子串开始所在的下标
        */
        int left, right, size = s.size(), flag = 0, max_s = 0, max_l = 0;
        /*哨兵点开始设置在第一位*/
        while (flag < size)
        {
            /*设置左右两个指针,每次flag更新后指针向两边散开*/
            left = flag;
            right = flag;

            /*如果发现同样字符,那么很明显是回文,右指针继续往右走,直到找到不一样的,并更新flag,下次寻找从这里展开*/
            while (right + 1 < size && s[right] == s[right + 1]) right++;
            flag = right + 1;

            /*找到了不一样的,两个指针中间可能有同一个字符的回文,也可能没有,无所谓,接下来是要比较两个指针对应的字符是否相同*/
            while (left - 1 >= 0 && right + 1 < size && s[left - 1] == s[right + 1])
            {
                left--;
                right++;
            }

            /*此时回文长度已更新,与之前所保存的最长回文长度作比较,更新最长回文长度及下标*/
            if (right - left + 1 > max_l)
            {
                max_l = right - left + 1;
                max_s = left;
            }
        }
        return s.substr(max_s, max_l);
    }
};

上一篇下一篇

猜你喜欢

热点阅读