5. Longest Palindromic Substring

文章目录如下

(1)自己的思路

(2)自己的代码

(3)别人的思路

(4)别人的代码

(5)对比自己的不足之处

题目如下:

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)自己的思路

a.因为回文数是对称位置的字符相等,所以可以用栈来解决,因为栈的结构是先进后出,本身就具有对称性。

b.首先在遍历原字符串的每一个字符s[i]的时候,每个s[i]都需要跟栈顶元素相比较,当与栈顶相同时,说明与s[i]的对称位置上有一个与s[i]相同的元素,此时将s[i]存放在临时的回文数字符串tmppalindromic之中,并将栈顶的元素pop出。

c.当栈顶元素与s[i]不相同的时候,那么直接将s[i]push到栈中。并且此时代表着栈里面已经没有回文数字符串了,这个时候要把tmppalindromic保存到容器vector中。并将tmppalindromic初始化(tmppalindromic="")

d.当遍历完所有元素的时候,只需要比较vector中每个 tmppalindromic的长度即可,取出长度最长的tmppalindromic

e.因为栈只保存了回文数字符串一半的元素,所以返回之前,要还原原始的回文字符串。

(2)自己的代码

class Solution {
public:
    string longestPalindrome(string s) 
    {
        if (s.size() == 1)
            return s;

        bool popfinish = false;
        string tmppalindromic = "";
        vector<string> v;
        stack<char> st;


        for (int i = 0; i < s.size(); i++)
        {
            if (popfinish&&tmppalindromic.size() != 0)
            {
                v.push_back(tmppalindromic);
                tmppalindromic.clear();
            }
            
            if (st.empty() || st.top() != s[i])
            {
                st.push(s[i]);
                popfinish = true;
            }
            else if (st.top() == s[i])
            {
                tmppalindromic.append(&s[i]);
                st.pop();
                popfinish = false;
            }
        }

        if (tmppalindromic.size() != 0)
            v.push_back(tmppalindromic);

        string longestpalindromic = "";
        int longestlen = 0;

        for (int j = 0; j < v.size(); j++)
        {
            if(v[j].size()>longestlen)
            {
                longestlen = v[j].size();
                longestpalindromic = v[j];
            }

        }
    
        string reverselongestpalindromic = longestpalindromic;
        reverse(reverselongestpalindromic.begin(), reverselongestpalindromic.end());
        return reverselongestpalindromic+longestpalindromic;
    }
};

(3)别人的思路

a.使用动态规划的思想

b.构建二维数组f[j][i],以此用来表示下标j到下标i的范围的字符是不是一个回文字符串,如果f[j][i]为true,那么原始字符串s中,以s[j]为开始,以s[i]为结束字符串(包括s[j],s[i])构成一个回文字符串,否则,则不是。

c.判断一段字符是否为回文字符串的标准有两个,一个是整个字串只有两/相同的字符(eg:aa)或只有一个字符a,即(s[j] == s[i]) &&(i - j < 2)

,或者是在回文字符串的基础上,又在该回文字符串的两边有添加上了两个相同的字符,即(s[j] == s[i])&&(f[j + 1][i - 1])

d.使用max_len保存当前最长回文字符串的长度,如果发现有新的更长的回文字符串,那么及时更新max_len的值,并且更改最长回文字符串的初始位置为j。

class Solution {
public:
        string longestPalindrome(string s) {
            int const n = s.size();
            bool f[n][n];
            fill_n(&f[0][0], n * n, false);
            size_t max_len = 1, start = 0; 
            for (size_t i = 0; i < s.size(); i++) {
                    f[i][i] = true;
                    for (size_t j = 0; j < i; j++) {  
                            f[j][i] = (s[j] == s[i] && (i - j < 2 || f[j + 1][i - 1]));
                            if (f[j][i] && max_len < (i - j + 1)) {
                                    max_len = i - j + 1;
                                    start = j;
                            }
                    }
            }
            return s.substr(start, max_len);
    }
};

(5)对比自己的不足之处

a.首先自己的那种方法不能处理axa这种回文字符串,当初看到这道题的时候对回文字符串理解有误。

b.不能解决aaaa这种情况。

别人的方法很巧妙地使用二维数组来表示回文字符串的开头与结尾,而且使用动态的规划的思想,这种做法很值得学习与借鉴

原文地址:https://www.cnblogs.com/magicy/p/5330292.html