LeetCode #5 Longest Palindrome

Posted 大峰子的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode #5 Longest Palindrome相关的知识,希望对你有一定的参考价值。

Description


 

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

 

Sample


 

Input: "babad"

Output: "bab"

Note: "aba" is also a valid answer.
Input: "cbbd"

Output: "bb"

 

思路

  回文串是正着读、反着读都一样的串,比如 "a"、"level"、"noon"。

  解本道题最无脑的办法肯定是 O(n^3) ,这里不讨论了。

  我想到了一个 O(n^2) 的办法,由于回文串都是对称的,那么它的中点就十分关键,我们维护一个指针 i 指向回文串的中点,维护一个指针 j 确定回文串的长度,判断序列 S[ i-j .. i ] 与序列 S[ i .. i+j ] 的逆序列S‘ 是否相同,如果相同,让 j++。

  举个例子,如 abcba ,当 i = 2 (S[2] = c) 时,j 赋值为 1,使得 s[ i-1..i ] 与 s[ i..i+1 ] 的逆序列分别为 [bc]、[bc] ,两者是相同的,那么就让 j++ 以表示回文串的长度增加,之后再比较 S[i-2..i] 与 s[i..i+2] 的逆序列是否相同...

  还需要注意回文串的长度分奇偶,比如 "bb"、"bab" ,敲代码的时候也要分别对两种情况进行修改。

 

  我用 map 去优化这道题存储回文串的运行时间,红黑树实现的map 插入效率为 O(lgn) ,但是算法时间的上界主要受指针 i j 的影响,,所以算法的时间复杂度为 O(n^2 ) ,这儿我想玩玩 map 的比较函数,所以时间会久一点。实际上,用两个变量存储最大回文串的长度与最长回文串就好了。  

#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
class Solution {
public:
    string longestPalindrome(string s) {        
        int len = 0, maxlen = 0; 
        std::map<int, string, greater<int> > m; //use greater<> sort key instead of default less<>
        string substr = "";
        for (int i = 0; i < s.size(); ++i) {
            findPal(s, i-1, i+1, len, substr); // Palindrome is adjacent
            if (maxlen < len) {
                maxlen = len;
                m[len] = substr;
            }
            findPal(s, i, i+1, len, substr); // Palindrome is not adjacent
            if (maxlen < len) {
                maxlen = len;
                m[len] = substr;
            }
        }
        substr = m.begin()->second; //the first value means longestPalindrome
        return substr; 
    }
private:
    void findPal(const string& s, int left, int right, int& len, string& substring) {
        while (left >= 0 && right <= s.size()-1 && s[left] == s[right]) {
            left--;
            right++;
        }
        len = right -left -1; //subtract extra two lengths
        if (len < 1)
            return; //length of Palindrome must >= 1
        else 
            substring = s.substr(left+1, len);
    }
};

 

  其实还有一种办法可以更快,那就是采用 区间DP 的 manacher 算法。但是我没悟到,之后理解了会再更新这篇博客。

  

 

以上是关于LeetCode #5 Longest Palindrome的主要内容,如果未能解决你的问题,请参考以下文章

leetcode--5. Longest Palindromic Substring

#Leetcode# 5. Longest Palindromic Substring

LeetCode题解 #5 Longest Palindromic Substring

[LeetCode] 5 Longest Palindromic Substring

Leetcode #5. Longest Palindromic Substring

LeetCode 5_Longest Palindromic Substring