• 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这种情况。

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

  • 相关阅读:
    设计模式学习总结
    算法时间复杂度和空间复杂度表示
    SQLite简单使用
    接口,组合和继承的想法
    二叉树的学习
    Oracle 常用命令大汇总
    Oracle 最常用功能函数经典汇总
    oracle 常用command
    历史最牛演讲:Oracle总裁Yale演讲全文中英文对照
    深入abstract class和interface
  • 原文地址:https://www.cnblogs.com/magicy/p/5330292.html
Copyright © 2020-2023  润新知