45:Longest Palindromic Substring

来源:互联网 发布:奥特曼变身器模拟软件 编辑:程序博客网 时间:2024/05/10 22:01

题目:Given a string S, find the longest palindromic substring in S. You may assume that the maximum length
of S is 1000, and there exists one unique longest palindromic substring.

解析1(解法代码的思想及编写参考了网址http://articles.leetcode.com/longest-palindromic-substring-part-i):

We observe that a palindrome mirrors around its center. Therefore, a palindrome can be expanded from its center, and there are only 2N-1 such centers.

You might be asking why there are 2N-1 but not N centers? The reason is the center of a palindrome can be in between two letters. Such palindromes have even number of letters (such as “abba”) and its center are between the two ‘b’s.

Since expanding a palindrome around its center could take O(N) time, the overall complexity is O(N^2).

解题代码如下:

class Solution {public:        string longestPalindrome(string s) {                const int n = s.size();                string longest;                for (int i = 0; i != n; ++i) {                        //以 i 处为中心往左右扩展                        // 此时最长回文子字符串长度为奇数                        string tmp1 = expandAroundCenter(s, i, i);                        if (longest.size() < tmp1.size())                                longest = tmp1;                        if (i != n - 1) {                                // 以 i, i+ 1 为中心往左右扩展                                // 此时最长回文子字符串长度为偶数                                string tmp2 = expandAroundCenter(s, i, i + 1);                                if (longest.size() < tmp2.size())                                        longest = tmp2;                        }                }                return longest;        }private:        string expandAroundCenter(const string& s, int i, int j) {                const int n = s.size();                int l = i, r = j;                while (l >= 0 && r <= n - 1 && s[l] == s[r]) {                        --l, ++r;                }                return s.substr(l + 1, r - l - 1);        }};

解析2(解法代码的思想及编写参考了网址http://articles.leetcode.com/longest-palindromic-substring-part-i):

动态规划算法,假设状态 p[i, j] 表示字符串区间 [i, j] 是否为回文,则 p[i, j] = (p[i + 1, j - 1] && (s[i] == s[j]) 基准情况是 p[i, i]= true, p[i, i + 1] = (s[i+1] == s[i])。

运用动态规划算法,时间复杂度为O(n^2),但空间复杂度既可以为O(n^2)又可以为O(n),代码如下:

//动态规划算法//时间复杂度O(n^2),空间复杂度O(n^2)class Solution {public:        string longestPalindrome(string s) {                if (s.empty()) return "";                const int n = s.size();                //初始化 table, 全为 false;               // table[i][j] 表示区间 [i, j] 是否为回文                bool table[n][n] = {false};                for (int i = 0; i != n; ++i)                        table[i][i] = true;                int max_len = 1; // 回文子字符串最长长度                int start = 0; // 回文子字符串的开始指标                for (int l = 2; l <= n; ++l)                        for (int i = 0; i <= n - l; ++i) {                                int j = i + l - 1;                                if (l == 2) tabel[i][i + 1] = (s[i] == s[i + 1]);                                else                                        table[i][j] = (s[i] == s[j]) && table[i + 1][j - 1];                                if (table[i][j] && max_len < l) {                                                max_len = l;                                                start = i;                                }                        }                return s.substr(start, max_len);        }};

解析3:利用 manacher’s algorithm,时间复杂度为 O(n),空间复杂度为 O(n),可参考的博客为 http://blog.csdn.net/hopeztm/article/details/7932245 和 http://www.cnblogs.com/grandyang/p/4475985.html。代码如下:

// Manacher's algorithm// 时间复杂度 O(N),空间复杂度 O(N)class Solution {public:        string longestPalindrome(string s) {                string t = preProcess(s);                cout << t << endl;                const int n = t.size();                int len[n];                int c = 0, r = 0;                int max_len = 0, center_index = 0;                for (int i = 1; i < n - 1; ++i) {                        int i_mirror = 2 * c - i;                        len[i] = (r > i) ? min(r - i, len[i_mirror]) : 0;                        while (t[i + len[i] + 1] == t[i - len[i] - 1])                                ++len[i];                        if (r < i + len[i]) {                                r = i + len[i];                                c = i;                        }                        if (max_len < len[i]) {                                max_len = len[i];                                center_index = i;                        }                }                return s.substr((center_index - 1 - max_len) / 2, max_len);        }private:        string preProcess(const string& s) {                const int n = s.size();                if (n == 0) return "^$";                string ret = "^";                for (int i = 0; i < n; ++i) {                        ret += "#";                        ret += s[i];                }                ret += "#$";                return ret;        }  };
1 0
原创粉丝点击